2011-02-02 4 views
0

У меня есть таблица событий и несколько подтипов разных типов для определения каждого события.Является ли это адекватным первичным ключом?

Таблица событий имеет идентификатор, (возможно, не уникальное) Datetime, userId и код типа события.

Для таблиц типа события, скажем, ExerciseStart ... is EventId имеет достаточный первичный ключ? Каждое событие имеет только один тип, поэтому его никогда не следует удваивать. И полезно ли включать дату и время в подкатегории, даже, возможно, в качестве составного первичного ключа, чтобы избежать случайного удвоения и, возможно, упростить создание запросов? (хотя это также было бы лишним я чувствую).

(Если я не должен был использовать DATETIME и TypeCode события в качестве ключа соединения, но это, кажется потенциально более рискованным для меня)

+1

Это поможет, если вы предоставите использование некоторых особенностей структуры таблиц. В другой заметке, всякий раз, когда вы используете суррогатный ключ (я предполагаю, что значение EventId является автоматически увеличивающимся значением), вы также должны определить другое уникальное ограничение для таблицы, состоящей из столбцов, отличных от PK. Например, в вашей таблице событий, что еще уникально идентифицирует событие: DateTime, UserId и TypeCode вместе? – Thomas

+0

User/DateTime/Typecode теоретически должен быть уникальным, я думаю. Я до сих пор не привык к тому, что у меня нет синтетического ключа, потому что я учился в школе и занимаюсь в течение пары лет. Здесь есть дополнительная информация о конкретной базе данных: http://stackoverflow.com/questions/4801628/one-table-or-many-for-many-different-but-interacting-events – Damon

+1

@Damon, К сожалению, некоторые данные курсы управления полностью не позволяют научить разумному использованию ключей в дизайне базы данных.Я встретил других, как вы, которые, похоже, узнали, что заслуживают внимания только суррогатные ключи. Это непрактично в реальном мире, где естественные ключи гораздо важнее для достижения успешных результатов. – sqlvogel

ответ

0

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

Это может быть что-то вроде этого:

CREATE TABLE events(
    event_id SERIAL PRIMARY KEY, 
    ... other fields 
); 

CREATE TABLE event_typeN(
    event_id BIGINT UNSIGNED PRIMARY KEY, 
    ...other fields, 
    FOREIGN KEY(event_id) REFERENCES events(event_id) 
); 
+0

Да, у меня есть что-то в этом роде. Мой вопрос более конкретно о том, действительно ли мне нужен первичный ключ sperate для моей таблицы event_typeN, поскольку у каждого события есть отдельный родитель с его собственным уникальным ключом, поэтому почему бы просто не использовать внешний ключ. – Damon

+0

Таблицы с различными типами событий нуждаются в первичной (как почти любые тальбы), поэтому наличие event_id в типеN в качестве первичного ключа в порядке. – Oleg

0

Использование стандартного SQL ...

Обычный способ сделать «Наследование» или «подклассы» должен иметь ключ соединения на (event_type, event_ID) и использования этот ключ в ссылочных таблицах подтипа с ограничением CHECK, чтобы гарантировать, что event_type подходит для этого подтипа, например CHECK (event_type = 'Exercise start').

Дополнительным касанием является то, что event_type DEFAULT в таблице «подтип» снова соответствует соответствующему типу, например. event_type VARCHAR(20) DEFAULT 'Exercise start' NOT NULL.

структура может выглядеть следующим образом:

CREATE TABLE EventTypes 
(
event_type VARCHAR(20) NOT NULL PRIMARY KEY 
); 

CREATE TABLE Events 
(
event_ID CHAR(10) NOT NULL, 
event_type VARCHAR(20) NOT NULL 
    REFERENCES EventTypes (event_type), 
event_date DATE NOT NULL, 
PRIMARY KEY (event_type, event_ID) 
); 

CREATE TABLE ExerciseStartEvents 
(
event_ID CHAR(10) NOT NULL, 
event_type VARCHAR(20) DEFAULT 'Exercise start' NOT NULL 
    CHECK (event_type = 'Exercise start'), 
FOREIGN KEY (event_type, event_ID) 
    REFERENCES Events (event_type, event_ID), 
PRIMARY KEY (event_type, event_ID), 
exercise_description VARCHAR(30) -- etc -- 
); 

Однако есть большая проблема с MYSQL в том, что она не обеспечивает CHECK ограничений :([Как можно терпеть это за меня!] Так чтобы ответить на ваш вопрос, имеющий простой ключ на event_ID в одиночку не является адекватным, потому что не может обеспечить соответствующий тип в таблицах «подтипа».

Хотя это может быть заманчиво «содействовать» event_ID ключевым кандидатом в таблице подтипов это может быть не очень хорошая идея. ould допускает, чтобы в таблице отображалась только одна строка для заданного event_ID, если эта строка неправильного типа, это предотвратит вставку строки с правильным типом!

Решение? Перейти к лучшей реализации SQL;)

+0

@onedaywhen. Можете ли вы объяснить, как ключ ID «предотвращает дублирование»? – PerformanceDBA

+0

Итак, утверждение, что «ID-ключи предотвращают дубликаты» явно ложно. – PerformanceDBA

+0

Причина «предотвращения дубликатов» заключается в том, что при программировании с базой данных существует много ситуаций, когда вам нужно вернуть 1 конкретную запись и с помощью синтетического автоматически увеличивающего первичный ключ, когда вы запрашиваете запись по ключу, вы всегда будете верните, несмотря ни на что. Насколько я понимаю, именно эти ключи предотвращают определенное дублирование, которое вызывает большую озабоченность у многих разработчиков. но не тот, который вызывает озабоченность у дизайнеров db. – Damon

Смежные вопросы