Как создать реляционную схему со следующими таблицами? - PullRequest
0 голосов
/ 15 августа 2010

В настоящее время у меня есть три таблицы.

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:

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 соответственно увеличивается, а данные из дочерней таблицы также зацикливаются. Таблица GrandParent и Parent связаны с полями TEL и G_COUNTER. и родительская таблица и дочерняя таблица связаны с полями TEL, G_COUNTER, P_COUNTER.

Теперь я хочу удалить эти счетчики и заменить их первичным ключом и внешним ключом, чтобы связать таблицу GrandParent, Parent и Child. Теперь, как мне это сделать?

Заранее благодарю за помощь.

Ответы [ 2 ]

1 голос
/ 15 августа 2010

Итак, у вас есть составные ключи и предположительно неявные отношения, которые вы хотите заменить соответствующими столбцами первичного ключа и внешними ключами.

Способ решения этой проблемы состоит из пяти простых частей:

  1. Добавление новых столбцов в таблицы.
  2. Заполнение столбцов первичного ключа.
  3. Заполните столбцы внешнего ключа.
  4. Добавьте ограничения.
  5. Отбросьте столбцы с обязательными аргументами.

Я буду работать с этим, используя синтаксис 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>

Шаг 1: Добавьте новые столбцы

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: Заполните первичные ключи

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:Заполните внешние ключи

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: Добавьте ограничения

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: Удалите обязательные столбцы

Я предполагаю, что 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>

Для обслуживания первичных ключей требуются разные методы в разных вариантах СУБД.Oracle использует последовательности, SQL Server использует AUTO INCREMENT.Это отдельный вопрос, который уже был освещен в SO.

1 голос
/ 15 августа 2010

Все, что вам нужно, это один стол.

create table Family
(
member_id,
parent_id references member_id,
level, --not strictly necessary, but may save you time later
any_other_column

) 

Oracle:

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

Рекомендуемое значение:

...