首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用下表创建关系模式?

如何用下表创建关系模式?
EN

Stack Overflow用户
提问于 2010-08-15 08:20:17
回答 2查看 4.6K关注 0票数 0

目前我有三张表。

代码语言:javascript
运行
复制
GrandParent( tel int, G_Counter int, GField varchar(10));
Parent( tel int, G_Counter int, P_counter int, PField Varchar(5));
Child(tel int, G_counter int, P_counter int, C_Counter int, CField Varchar(3));

这些桌子都是扁平的桌子。并且这些表自身循环,并且该循环由计数器确定。我需要删除这些计数器,并使用PK和FK创建一个关系模式。

样本数据是

GrandParent:

代码语言:javascript
运行
复制
TEL    G_COUNTER  GField
 t1      1          ga
 t2      1          gb
 t2      2          gc
 t3      1          gd

父级:

代码语言:javascript
运行
复制
TEL     G_COUNTER   P_COUNTER  PFIELD
 t1        1           1         pa
 t1        1           2         pb
 t1        1           3         pc
 t2        1           1         pd
 t3        1           1         pe

孩子:

代码语言:javascript
运行
复制
TEL     G_COUNTER   P_COUNTER  C_COUNTER  CFIELD
 t1        1           1          1         ca
 t1        1           1          2         cb
 t1        1           1          3         cc
 t2        1           1          1         cd
 t2        1           1          2         ce
 t3        1           1          1         cd

GrandParent循环上的数据和G_COUNTER递增1。对于TEL t2,G_COUNTER是1和2。父表上的数据也会循环。P_COUNTER会相应地递增,子表上的数据也会循环。GrandParent表和父表与TEL和G_COUNTER字段相关联。父表和子表与TEL、G_COUNTER、P_COUNTER字段相关联。

现在我想删除这些计数器,并将其替换为主键和外键,以关联GrandParent表、父表和子表。现在我该怎么做呢?

提前感谢您的帮助。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-08-15 16:17:44

因此,您有复合键和可能的隐式关系,您希望用适当的主键列和外键替换它们。

实现这一点的方法可以分为五个简单的部分:

将新列添加到主键和外键列中。constraints.

  • Drop
  1. 添加constraints.
  2. Drop

我将使用Oracle语法来解决这个问题,但同样的原则也适用于SQL Server。

代码语言:javascript
运行
复制
SQL> select * from grandparent
  2  /

TE  G_COUNTER GF
-- ---------- --
t1          1 ga
t2          1 gb
t2          2 gc
t3          1 gd

SQL> select * from parent
  2  /

TE  G_COUNTER  P_COUNTER PF
-- ---------- ---------- --
t1          1          1 pa
t1          1          2 pb
t1          1          3 pc
t2          1          1 pd
t3          1          1 pe

SQL> select * from child
  2  /

TE  G_COUNTER  P_COUNTER  C_COUNTER CF
-- ---------- ---------- ---------- --
t1          1          1          1 ca
t1          1          1          2 cb
t1          1          1          3 cc
t2          1          1          1 cd
t2          1          1          2 ce
t3          1          1          1 cd

6 rows selected.

SQL>

步骤1:添加新列

代码语言:javascript
运行
复制
SQL> alter table grandparent
  2      add g_id number
  3  /

Table altered.

SQL> alter table parent
  2      add p_id number
  3      add g_id number
  4  /

Table altered.


SQL> alter table child
  2      add c_id number
  3      add p_id number
  4  /

Table altered.

SQL>

步骤2:填充主键

代码语言:javascript
运行
复制
SQL> update grandparent
  2      set g_id = rownum
  3  /

4 rows updated.

SQL> update parent
  2      set p_id = rownum
  3  /

5 rows updated.

SQL> update child
  2      set c_id = rownum
  3  /

6 rows updated.

SQL>

步骤3:填充外键

代码语言:javascript
运行
复制
SQL> update parent p
  2      set g_id = ( select g_id
  3                   from grandparent g
  4                   where g.tel = p.tel
  5                   and   g.g_counter = p.g_counter)
  6  /

5 rows updated.

SQL> update child c
  2      set p_id = ( select p_id
  3                   from parent p
  4                   where p.tel = c.tel
  5                   and   p.g_counter = c.g_counter
  6                   and   p.p_counter = c.p_counter)
  7  /

6 rows updated.

SQL>

步骤4:添加约束

代码语言:javascript
运行
复制
SQL> alter table grandparent
  2      modify g_id not null
  3      add constraint g_pk primary key (g_id) using index
  4  /

Table altered.

SQL> alter table parent
  2      modify p_id not null
  3      add constraint p_g_fk foreign key (g_id)
  4          references grandparent (g_id)
  5      add constraint p_pk primary key (p_id) using index
  6  /

Table altered.

SQL> alter table child
  2      modify c_id not null
  3      add constraint c_p_fk foreign key (p_id)
  4          references parent (p_id)
  5      add constraint c_pk primary key (c_id) using index
  6  /

Table altered.

SQL>

步骤5:删除无用的列

我假设祖父母(电话、G_COUNTER)代表某种商业密钥。因此,我建议您添加一个唯一的约束来强制执行规则,而不是删除它们。对于父对象(G_ID,P_COUNTER)和子对象(G_ID,C_COUNTER)可能也是如此。你比我更了解你的数据。因此,以下语句表示您可能想要做的事情;请根据您的需要进行调整。

代码语言:javascript
运行
复制
SQL> alter table grandparent
  2      add constraint g_uk unique (tel, g_counter) using index
  3  /

Table altered.

SQL> alter table parent
  2      add constraint p_uk unique (g_id, p_counter) using index
  3  /

Table altered.

SQL> alter table parent
  2      drop column tel
  3  /

Table altered.

SQL> alter table parent
  2      drop column g_counter
  3  /

Table altered.

SQL> alter table child
  2      drop column tel
  3  /

Table altered.

SQL> alter table child
  2      drop column g_counter
  3  /

Table altered.

SQL> alter table child
  2      drop column p_counter
  3  /

Table altered.

SQL> alter table child
  2      add constraint c_uk unique (p_id, c_counter) using index
  3  /

Table altered.

SQL>

让我们检查一下表格:

代码语言:javascript
运行
复制
SQL> select * from grandparent
  2  /

TE  G_COUNTER GF       G_ID
-- ---------- -- ----------
t1          1 ga          1
t2          1 gb          2
t2          2 gc          3
t3          1 gd          4

SQL> select * from parent
  2  /

 P_COUNTER PF       P_ID       G_ID
---------- -- ---------- ----------
         1 pa          1          1
         2 pb          2          1
         3 pc          3          1
         1 pd          4          2
         1 pe          5          4

SQL> select * from child
  2  /

 C_COUNTER CF       C_ID       P_ID
---------- -- ---------- ----------
         1 ca          1          1
         2 cb          2          1
         3 cc          3          1
         1 cd          4          4
         2 ce          5          4
         1 cd          6          5

6 rows selected.

SQL>

在不同风格的DBMS中,维护主键需要不同的技术。Oracle使用序列,SQL Server使用自动增量。这是一个单独的问题,我们已经在SO中进行了讨论。

票数 1
EN

Stack Overflow用户

发布于 2010-08-15 08:28:43

您所需要的只是一张表。

代码语言:javascript
运行
复制
create table Family
(
member_id,
parent_id references member_id,
level, --not strictly necessary, but may save you time later
any_other_column

) 

Oracle:

代码语言:javascript
运行
复制
select 
    lpad(' ',2*(level-1)) || to_char(member_id) s

from 
    Family

start with parent_id is null
connect by prior member_id = parent_id ;

SQL Server:

http://msdn.microsoft.com/en-us/library/ms186243.aspx

推荐阅读:

  • Joe Celko's Trees and hierarchies in SQL for smarties
  • Joe Celko's thinking in sets (不太合适,但仍然强烈建议具有过程式思维的人使用基于集合的SQL数据库。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3485688

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档