Использование одного атрибута как первичного ключа, так и внешнего ключа в таблице подтипов - PullRequest
0 голосов
/ 06 июля 2018

У меня есть таблица супертипа (из ERD) с именем Card, и у этой таблицы есть два подтипа: Credit Card и Debit Card. У меня есть Primary Key в моей таблице Card с именем CardID.

Будет ли правильно, если я назначу Primary Key из Card в качестве внешнего ключа и первичного ключа Credit Card и Debit Card?

Как импортировать первичный ключ таблицы супертипа в его подтипы (код)? Я просто делаю это?

CREATE TABLE [Credit Card] (
    CreditCardNumber varchar(50) NOT NULL Primary Key,
    CreditCardNumber varchar(50) NOT NULL Foreign Key REFERENCES Card(CardID)
)

Ответы [ 3 ]

0 голосов
/ 06 июля 2018

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

То, как вы написали свой запрос, все равно, что сказать, что у вас есть два разных столбца с одним и тем же именем, как заявил GuidoG. Вы хотите что-то вроде этого:

CREATE TABLE [Credit Card] (
    CreditCardNumber varchar(50) NOT NULL Primary Key,
    ....(other cols)....,
    CONSTRAINT FK_CreditCard_Card Foreign Key (CreditCardNumber) REFERENCES Card(CardID)
)

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

В ответ на ваш комментарий: единственное, что не правильно из того, что вы говорите, это слово "но". Кажется, вам пришло в голову, что это «странно», если столбец - это и PK, и FK; это не. Это две совершенно не относящиеся к делу вещи, и SQL-серверу все равно. PK гарантирует, что каждая строка имеет разные значения в этом столбце. FK гарантирует, что значение должно существовать в возможных значениях столбца из другой таблицы. Никаких конфликтов вообще; кроме возможного философского / дизайнерского конфликта, который, конечно, происходит только в ВАШЕМ уме (не в структуре сервера sql), и который мой ответ (и многие другие) уже рассмотрел.

0 голосов
/ 06 июля 2018

Я думаю, вы хотите что-то вроде этого

create table dbo.[Credit Card] (
  CreditCardNumber varchar(50) not null,
  other columns ...

  constraint PK_CreditCardNumber primary key (CreditCardNumber),
  constraint FK_CreditCard_Card foreign key (CreditCardNumber) references Card(CardID)
)

Это будет работать, только если столбец CardID в таблице Card имеет то же определение, что и столбец CreditCardNumber в таблице Credit Card
Просто глядя на имена, это может быть не так?

В большинстве случаев лучше использовать поле дискриминатора и только одну таблицу.
Например

create table dbo.Card (
   CardNumber varchar(50) not null,
   CardType char(1) not null check (CardType in ('C', 'D')),

   CreditCardColumn1 varchar(50) null,
   CreditCardColumn2 varchar(50) null,

   DebitCardColumn1 varchar(50) null,

   constraint PK_CardNumber primary key (CardNumber),
)

Проверочное ограничение обеспечит сохранение в этом столбце только C или D.
Обе колонки для кредитной карты и дебетовой карты должны быть помещены в эту таблицу. Запрашиваемый вами запрос должен быть разным для каждого типа, таблица всегда будет одинаковой

Теперь, когда вам нужны все кредитные карты, просто наберите

select c.CardNumber,
       c.CardType,
       c.CreditCardColumn1,
       c.CreditCardColumn2
from   dbo.Card c
where  CardType = 'C'

и для всех дебетовых карт просто сделайте

select c.CardNumber,
       c.CardType,
       c.DebitCardColumn1
from   dbo.Card c
where  CardType = 'D'
0 голосов
/ 06 июля 2018

См. Документ \ SQL \ T-SQL

CREATE TABLE [Credit Card] (
    CreditCardNumber varchar(50) NOT NULL Primary Key,
    Foreign Key (CreditCardNumber) REFERENCES Card(CardID)
)
...