目前我有三张桌子。
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创建关系模式。
示例数据是
祖父母:
TEL G_COUNTER GField
t1 1 ga
t2 1 gb
t2 2 gc
t3 1 gd
父:
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
子:
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。 Parent上的数据也循环P_COUNTER相应地递增,Child表上的数据也循环。 GrandParent表和Parent表与TEL和G_COUNTER字段相关。父表和子表与TEL,G_COUNTER,P_COUNTER字段相关。
现在我想删除这些计数器并将其替换为主键和外键以关联GrandParent,Parent和Child表。现在我该怎么做?
提前感谢您的帮助。
答案 0 :(得分:1)
您只需要一张桌子。
create table Family
(
member_id,
parent_id references member_id,
level, --not strictly necessary, but may save you time later
any_other_column
)
甲骨文:
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
推荐阅读:
答案 1 :(得分:1)
因此,您有复合键和可能是隐式关系,您希望用适当的主键列和外键替换它们。
接近这个问题的方法有五个简单的部分:
我将使用Oracle语法解决这个问题,但SQL Server中的原理相同。
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>
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>
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>
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>
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>
我假设GRANDPARENT(TEL,G_COUNTER)代表某种商业密钥。因此,我建议您添加一个唯一约束来强制执行规则,而不是删除它们。对于PARENT(G_ID,P_COUNTER)和CHILD(G_ID,C_COUNTER)也是如此。你比我更了解你的数据。因此,以下陈述表明您可能想要做的事情;根据您的需要调整它们。
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>
让我们检查表格:
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使用AUTO INCREMENT。这是一个单独的问题,已经被SO所涵盖。