Ответы на ваши индивидуальные вопросы
Если я хочу добавить столбец с Club
описанием владельца, который также будет участником, каков наилучший подход, если один и тот же член не будет указан дважды?
Если - как указано в ваших спецификациях a Person can be a Member of only one Club
- и вы заинтересованы в том, чтобы сохранить этот элемент данных просто как true или false , одним из вариантов является добавление столбца BIT(1)
или BOOLEAN
( TINYINT
) в Person
таблицу, и вы можете вызвать этот столбец IsClubOwner
. Таким образом, вы можете зарегистрировать тот факт, что определенный человек является владельцем клуба исключительно один раз. Кроме того, этот метод также позволяет сохранить несколько человек в качестве владельцев одного и того же клуба . Вы можете увидеть логическое описание этого подхода на рисунке 1 .
Тем не менее, вы ищете лучший подход, и, согласно моему опыту, такой подход влечет за собой разработку гораздо более расширяемой и универсальной структуры. В этом отношении выполните последовательность действий по моделированию для этих и других пунктов ниже в разделах, озаглавленных «Охват оставшихся спецификаций», «Лицо как член нескольких клубов» и «Член и владелец как отдельные типы сущностей».
Должен ли я поставить все мои таблицы на автоматическое увеличение id
или это будет плохой идеей? (ПРЕИМУЩЕСТВА / минусы?)
Если вы сталкиваетесь с явным требованием, которое указывает определение таблицы со столбцом таких характеристик, и этот столбец имеет действительное контекстное значение или служит определенной цели, например, является суррогатом для широкого естественного ПЕРВИЧНОГО КЛЮЧА (PK), тогда да, Вы должны идти по этому пути.
В противном случае, если у вас нет указанного требования, я считаю, что это было бы излишним, поскольку вы должны хранить и управлять бессмысленным дополнительным столбцом и (возможно?) Также дополнительным индексом в вашей базе данных.
Как обычно, вы должны проанализировать каждый случай вместе с его общими последствиями, чтобы решить, как продолжать.
Если я добавлю внешние ключи на вкладку внешних ключей, будут ли они автоматически соответствовать правильной таблице или я должен добавить их также в столбцы?
В связи с этим я советую вам создавать структуру базы данных вручную, кодировать свои собственные DDL
заявления, пока вы не получите четкое представление о предмете. Если вы сделаете это, вам будет легче понять процессы, которые графические инструменты выполняют «под капотом».
Для меня, например, создание заявления вроде следующего:
CONSTRAINT FK_PersonPhoneNumber_to_Person FOREIGN KEY (PersonId)
REFERENCES Person (PersonId)
Это гораздо более поучительно, чем использование инструментов с графическим интерфейсом для выполнения подобных задач, особенно сейчас, когда вы строите свои первые проекты.
И мой, пожалуй, самый нудистый вопрос из всех ... Я помещаю внешние ключи phone_number
и email
в их соответствующие таблицы, ссылающиеся на person_id
или я должен поместить phone_number
и email
ids
в таблицу лиц?
Лично я думаю, что этот и все другие ваши вопросы полностью актуальны и хорошо контекстуализированы .
Возвращаясь к техническим аспектам, которые нас интересуют, этот точный запрос предлагает хорошую возможность рассмотреть два следующих утверждения:
A Person can be reached through zero-one-or-many PhoneNumbers
A PhoneNumber can be used to reach one-to-many People
Таким образом, можно сделать вывод, что между многими существует взаимосвязь, Person
и PhoneNumber
поэтому я предлагаю создать ассоциативную таблицу, названную PersonPhoneNumber
для представления указанных взаимосвязей в вашей базе данных. PK этой таблицы должен состоять из двух разных столбцов: PersonId
(FOREIGN KEY [FK] указывает на Person.PersonId
) и PhoneNumber
(FK, который ссылается на PhoneNumber.Number
). Логическое описание всего вышеперечисленного см. На рисунке 1 .
С другой стороны, давайте рассмотрим два следующих предложения:
A Person can be contacted via zero-one-or-many EmailAddresses
An EmailAddress can be used to contact exactly one Person
Затем, да, вы должны установить FK, ссылающийся Person
на EmailAddress
таблицу, и эта таблица также должна иметь составной PK, который будет состоять из столбцов PersonId
и Address
. Таким образом, вы можете убедиться в том , что та же комбинация EmailAddress.PersonId
и EmailAddress.Address
может быть вставлен только один раз.
Если вы также хотите, чтобы данные EmailAddres.Address
могли храниться в одной строке, вам просто нужно установить УНИКАЛЬНОЕ ОГРАНИЧЕНИЕ для этого столбца.
Предлагаемые логические модели данных
Чтобы более четко изложить свои предложения, я включил четыре различные логические модели IDEF1X [1] , которые показаны на рис. 1 , рис. 2 , рис. 3 и рис. 4 . Я предоставлю объяснение наиболее важных функций, отображаемых в каждой из них в соответствующих разделах. Вы также можете скачать из Dropbox PDF, который объединяет в одной модели большинство обсуждаемых элементов.
Покрытие ваших оставшихся спецификаций
Отношения людей и адреса
Давайте рассмотрим два следующих (слегка перефразированных) утверждения, которые имеют отношение к людям и адресам :
A Person can only have one Address
An Address can belong to different People (couples or siblings)
Таким образом, чтобы справиться с этими ограничениями, вы можете выбрать реализацию модели данных, аналогичной той, что показана на рисунке 1 .
Принимая во внимание указанную модель, необходимо выполнить следующие шаги:
Создайте таблицу под названием PersonAddress
фиксация отношений между Person
и Address
. Установите столбцы PersonId
и AddressId
в качестве составного ПК этой таблицы.
Сконфигурируйте UNIQUE CONSTRAINT для PersonAddress.PersonId
столбца, чтобы гарантировать, что конкретное значение может быть вставлено не более чем в одну строку указанной таблицы. На логическом уровне это обстоятельство подразумевает, что PersonAddress.PersonId
стал АЛЬТЕРНАТИВНЫМ КЛЮЧОМ [2] .
Если значение AddressId
в определенной PersonAddress
попытке вставки еще не сохранено, то пусть вставка продолжается, в противном случае, когда такое значение уже существует в строке, вы должны проверить, что (a) PersonId
зарегистрированный пользователь AddressId
также зарегистрирован как Marriage.WifeId
если PersonId
это мужчина (данные, полученные с помощью Person.GenreCode
) или (b), PersonId
то Marriage.HusbandId
когда PersonId
это женщина, (также полученная на основании Person.GenreCode
). Если в соответствующей ситуации выполняется одно из этих условий, вам следует разрешить INSERT продолжить.
Если вышеуказанные условия не были выполнены, есть шанс, что PersonAddress
вставка будет успешной. Вы должны проверить, что PersonId
значение, участвующее в указанной попытке вставки, делит хотя бы одно значение Progeny.ParentId
с тем PersonId
, которое уже зарегистрировало PersonAddress.AddressId
. Если это условие выполняется, то это означает, что они хранятся как Siblings
в базе данных, поэтому этот INSERT должен быть выполнен успешно.
Как и в любой реализации реляционной базы данных, вам следует серьезно подумать о выполнении ваших DML
операций внутри транзакций ACID, чтобы вы могли защитить целостность и непротиворечивость данных, с которыми вы работаете.
Отвечая на требования, которые вы добавили в комментариях: Адреса и номера телефонов, служащие одинаково Клубам и Людям
При условии, что вы хотите дать возможность адресам и телефонным номерам обслуживать как людей, так и клубы , вы можете использовать отношения супертип-подтип . Вот ответ, в котором я даю более подробное описание такого рода структур, если вам это интересно.
В настоящем сценарии вы можете определить Person
и Club
как подтипы новой сущности, названной Party
, термин, обычно используемый в юридических кругах для обозначения (а) человека или (б) группы лиц (как отмечено в смысле № 6 ). С помощью этого метода отношения между Addresses
(или PhoneNumbers
) и People
и Clubs
будут определены через Party
супертип. См. Рисунок 2 для описания этого предложения.
Сторона и адрес
Таким образом, мы можем прочитать в этой новой модели, что:
A Party keeps zero-one-or-many Addresses
An Address is kept by one-to-many Parties
Таким образом, существует много-ко-многим с участием Party
и Address
что выражается путем PartyAddress
субъекта.
Вечеринка и номер телефона
Кроме того, мы можем интерпретировать это:
A Party is reached through zero-one-or-many PhoneNumbers
A PhoneNumber is used by one-to-many Parties
Вот почему я добавил PartyPhoneNumber
сущность, которая описывает связь «многие ко многим», которая действует между типами сущностей Party
и PhoneNumber
.
Вечеринка и клуб или человек
Затем также можно прочитать, что:
A Party is either a Club or a Person
Следовательно, Party
поставляет соединение из либо Clubs
или People
к Addresses
(или PhoneNumbers
).
Человек как член нескольких клубов
Как @aldwinaldwin упоминает в своем ответе, если вы хотите предоставить функциональность человеку, который будет членом нескольких клубов , то вы можете включить таблицу под названием ClubMember
, которая будет выступать в качестве другого отношения многих ко многим, на этот раз, естественно, , соединяющий Person
и Club
.
Я хочу добавить к вышесказанному, что эта таблица также может быть полезна для сохранения любого конкретного человека в качестве владельца нескольких клубов посредством включения уже упомянутой IsClubOwner
логической колонки. Фактически, можно сказать, что эта новая таблица является представлением целочисленного типа сущности сама по себе.
Как показано на рисунке 3 , для такой таблицы требуется составной PK, состоящий из столбцов ClubId
и MemberId
( которому присвоено имя роли [3]PersonId
), и эти столбцы должны быть определены также как FK, указывающие, соответственно, на Club
и Person
.
Более адаптируемая структура
Используя этот параметр, вы также можете соблюдать первоначальное правило, которое гласит, что a Person can be a member of only one Club
вам нужно просто добавить УНИКАЛЬНОЕ ОГРАНИЧЕНИЕ в MemberId
столбец, чтобы определенное значение можно было ввести не более одного раза. Итак, как вы можете заметить, эта структура гораздо более адаптируема, чем та, что показана на рисунке 1 , поскольку, отбрасывая УНИКАЛЬНОЕ ОГРАНИЧЕНИЕ (или ИНДЕКС), вы открываете вышеупомянутую функциональность, позволяющую человеку стать членом различных клубов на в то же время.
Член и владелец как отдельные типы объектов
Как вы знаете, хранение несколько фактов о роли осуществляется с помощью человека , как владелец из клуба -besides его лишь существования в истинном или ложном attribute- может быть очень выгодным. Например, вы можете сохранить дату вступления в силу , в которой определенный человек стал владельцем из клуба , следовательно , вы можете справиться с этой ситуацией, вводя отдельный тип объекта под названием ClubOwner
, представленный на рисунке 4 .
Как только вы построите таблицу на основе этого нового типа сущности, вы можете добавить подходящие столбцы, которые представляют характеристики, которые вступают в игру исключительно, когда a Person
является Owner
a of Club
. Как изображено, эта таблица будет содержать PK, состоящий из ссылок на столбцы FK Person.PersonId
и Club.ClubId
, таким образом, любую комбинацию ClubOwner.OwnerId
(или ClubOwner.PersonId
, если вы предпочитаете) и ClubOwner.ClubId
может быть вставлена только в одну возможность.
Конечно, с этой конфигурацией вы все еще можете получить в логической форме, если a Person
является Owner
частным Club
с помощью запроса, который возвращает скалярное значение, которое может быть оценено как true или false .
Ноты
1. Определение интеграции для информационного моделирования ( IDEF1X ) - это очень рекомендуемый метод моделирования данных, который был определен в качестве стандарта в декабре 1993 года Национальным институтом стандартов и технологий США ( NIST ). Оно прочно основано на (а) некоторые из теоретических работ , автором которого является отправителем в реляционной модели , т.е. д - р Ф. Кодда ; (б) теория сущностей-отношений , разработанная доктором П.П. Ченом ; а также о (c) методике проектирования логических баз данных , созданной Робертом Г. Брауном . Стоит отметить, что IDEF1X былформализован с помощью логики первого порядка .
2. ALTERNATE KEY - это атрибут (или комбинация атрибутов), который содержит значения, которые однозначно идентифицируют вхождение объекта, но не были выбраны в качестве PK соответствующего типа объекта; каждый тип сущности может иметь ноль, один или несколько АЛЬТЕРНАТИВНЫХ КЛЮЧЕЙ. В модели IDEF1X они обозначены как «AK» плюс его соответствующий номер, например, AK1, AK2 и т. Д. Они обычно реализуются в структуре SQL DDL через УНИКАЛЬНОЕ ОГРАНИЧЕНИЕ (или УНИКАЛЬНЫЙ ИНДЕКС ).
3. Имена ролей - это обозначения (или псевдонимы), присвоенные атрибутам FK, чтобы выразить значение, которое они имеют в рамках своей соответствующей сущности. Их использование рекомендуется с 1970 г. д-ром Коддом в его оригинальной работе под названием «Реляционная модель данных для больших общих банков данных» . Со своей стороны, IDEF1X - сохранение верности в отношении реляционных практик - также выступает за именование ролей.
clubId
телефона также и оставить ноль или клуб или человека?