Ограничения в Postgresql - PullRequest
1 голос
/ 13 ноября 2011

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

Вот соответствующие таблицы для этого вопроса в моей базе данных:

MusicGroup(idG, name, city, country, year)

Edition(idG, titleE, year, editor)
idG : FK(MusicGroup)

Music(idG, titleM, length)
idG : FK(MusicGroup)

Album(idG, titleE)
idG, titleE : FK(Edition)

Track(idG, titleE, number, titleM)
idG, titleE : FK(Album)
idG, titleM : FK(Music)

Single(idG, titleE, titleM)
idG, titleE : FK(Edition)
idG, titleM : FK(Music)

Вот инструкция по созданию базы данных (также сделанная мной):

create table MusicGroup (idG char(10) not null
    unique(idG),
    name varchar(255) not null,
    city varchar(255) not null,
    country varchar(255) not null,
    year numeric(6,0) not null,
    primary key (idG))


create table Edition (idG char(10) not null,
    titleE varchar(50) not null,
    year numeric(6,0) not null,
    editor varchar(255) not null,
    primary key (idG, titleE),
    foreign key(idG) references MusicGroup(idG))


create table Music (idG char(10) not null,
    titleM varchar(50) not null
    unique(titleM),
    length float(1) not null,
    primary key (idG, titleM),
    foreign key(idG) references MusicGroup(idG))


create table Album (idG char(10) not null,
    titleE varchar(50) not null,
    primary key (idG, titleE),
    foreign key(idG, titleE) references Edition(idG, titleE))


create table Track (idG char(10) not null,
    titleE varchar(50) not null,
    number smallint not null,
    titleM varchar(50) not null,
    primary key (idG, titleE, number),
    foreign key(idG, titleE) references Album(idG, titleE),
    foreign key(idG, titleM) references Music(idG, titleM))


create table Single (idG char(10) not null,
    titleE varchar(50) not null,
    titleM varchar(50) not null,
    primary key (idG, titleE),
    foreign key(idG, titleE) references Edition(idG, titleE),
    foreign key(idG, titleM) references Music(idG, titleM))

Я должен добавить следующее ограничение: Название альбома должно быть названием одного из треков на этом альбоме, и этот трек должен быть уже опубликован как сингл.

Итак, я попытался решить следующим образом:

alter table Album
add foreign key (idG, titleE, titleE) references Track(idG, titleE, titleM)

alter table Track
add foreign key (idG, titleE, titleM) references Single(idG, titleE, titleM)

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

Заранее большое спасибо за любую помощь:)

Ответы [ 4 ]

1 голос
/ 14 ноября 2011

С этим набором определений таблиц SQL FK - не лучший способ.Цель для FK, в которой вы нуждаетесь, - это СОЕДИНЕНИЕ между Треком и Синглом (чтобы выразить мнение, что название альбома должно называться Трек на этом альбоме И должно называться синглом).способ сделать это в SQL, за исключением понижения уровня NF проекта и введения избыточности (и даже тогда я не уверен, что этого будет достаточно в данном конкретном случае).

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

Обратите внимание, что хотя стандарт SQL позволяет писать практически все в ограничении CHECK, многие реализации предлагают только очень ограниченное подмножествополной «теоретической» функциональности, определенной стандартом.

0 голосов
/ 07 сентября 2012

первое, что вам нужно сделать, это получить уникальное ограничение, на которое вы можете сослаться, поскольку вы разрешаете дублирование заголовков для треков на компакт-диске, вам придется изменить это:помогает.Обратите внимание, что отложенный ключ будет применен во время принятия, так как мы не будем знать, что он действителен до этого момента.

0 голосов
/ 14 ноября 2011

Первый:

  • я бы позволил каждой таблице иметь первичный ключ с одним полем (не составной). (это вызовет необходимость в другом ограничении: альбом или издание не могут содержать фрагменты от нескольких исполнителей). Я также чувствую сильную терпимость, чтобы сделать эти суррогатные идентификаторы числовыми.
  • вы делаете имена уникальными для многих ваших сущностей. Это, вероятно, не будет иметь место ("лучшие хиты")
  • некоторые наименования: большинство людей настоятельно рекомендуют использовать MixedCase в TableNames (это заставляет вас заключать в кавычки идентификаторы каждый раз, и его сложнее читать, это также может привести к путанице в СУБД, которая может быть или не быть существенной в зависимости от фазы луны)
  • больше имен: я бы назвал трек то, что вы называете Музыка
  • Я бы назвал исполнителя тем, что вы называете MusicGroups
  • Я бы переименовал Track в нечто вроде «tracklist» или «album_toc» (или track_album_relation).
  • (возможно), я бы объединил сингл и альбом в одну сущность ("zrecord") и добавил бы тег типа, это также позволило бы синглам иметь обратную сторону, разрешить EP и т. Д.
  • Я не знаю, какова цель издания. Вам может даже понадобиться подобный механизм («версии», ремастеринг ») для отдельных треков.

... больше подписок.

0 голосов
/ 13 ноября 2011

Я не думаю, что внешний ключ - лучший способ установить это ограничение. Я бы определенно добавил для этого триггер .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...