Зачем нужен primary key? @ DeForum.ru
DeДверь  
Логин:  
Пароль:  
  Автологин  
   
Разместить рекламу
Письмо админу
Правила | FAQ | *Поиск | Наша команда | Регистрация | Вход
 
 
 Страница 1 из 1 [ Сообщений: 9 ] 
*   Список форумов / Начинка и техника / Программирование для WWW » ответить » создать топик « | »
Автор Сообщение
Арт Директор Муж.
новый человек
15
Сообщения: 128
Зарегистрирован: 07.09.05
Откуда: Москва
Заголовок сообщения: Зачем нужен primary key?
Сообщение Добавлено: 5 Март 2008, 23:26:48 
Кто может сказать, каждая ли таблица должна содержать primary key?
В чем его особая роль?
Где почитать?… :insane:

_________________
{'L'}('J')
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 5 Март 2008, 23:39:22 
Обе утверждения истинны:

1. Таблица не обязана содержать первичный ключ.
2. Правильно спроектированная реляционная БД не должна содержать таблиц, не имеющих первичного ключа.

Обоснование есть у Дейта. Ну и у Кодда, разумеется. Цитировать здесь не буду, поскольку оно предполагает понимание концепции "реляционная БД". Впрочем, оно также хорошо раскрыто у Дейта. Ну и у Кодда, разумеется.
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Сообщение Добавлено: 6 Март 2008, 04:37:51 
Что бы точно знать, что каждая строка в таблице уникальна - нужен первичный ключ. Первичные ключи делят на натуральные и суррогатные.

Натуральный первичный ключ:

Допустим таблица заказов состоит из 3-х столбиков:
Код:
Дата и время        | Номер клиента | Описание заказа
--------------------+---------------+-------------------
2008-03-01 10:15:20 |      2        | Книга
2008-03-01 10:17:30 |      1        | Ручка
2008-03-01 10:18:10 |      3        | Стерка
В данной таблице 1 и 2 столбики вместе составляют Первичный Ключ.
Потому что они делают каждую запись (строчку) уникальной.

Докажем это:

Строка:
Код:
2008-03-01 10:17:30 |      1        | Ручка
будет уникальной, потому что клиент не должен иметь возможность сделать два заказа одновременно (в ту же секунду).

Одного времени (столбик 1) не достаточно что бы определить уникальность строки. Нужен еще стоблик 2.
Потому что два разных клиента могут заказать товар одновременно:
Код:
Дата и время        | Номер клиента | Описание заказа
--------------------+---------------+-------------------
2008-03-01 10:17:30 |      1        | Ручка
2008-03-01 10:17:30 |      2        | Ручка

Что бы найти конкретную строку, вам надо знать по крайней мере: дату и номер клиента.
Если вы знаете только дату (или только клиента) - вы рискуете получить несколько строк.
Вместе: Дата и Номер клиента - это первичный ключ.

---------------------------------------------------------
Суррогатный первичный ключ:

Не всегда удобно иметь первичный ключ состоящий из 2-х и более столбиков.
Потому что не всегда удобно искать строку по значениям 2-х и более столбиков.

Поэтому искусственно добавляют еще один столбик (например Номер заказа):
Код:
Номер заказа |Дата и время        | Номер клиента | Описание заказа
-------------+--------------------+---------------+-------------------
      1      |2008-03-01 10:15:20 |      2        | Книга
      2      |2008-03-01 10:17:30 |      1        | Ручка
      3      |2008-03-01 10:18:10 |      3        | Стерка
Здесь "Номер заказа" автоматически генерируется для каждого заказа (каждое число на единицу больше чем предыдущее.)

Теперь что бы найти конкретную строку - достаточно знать только "Номер заказа".

Это называется суррогатный первичный ключ. Потому что мы искусственно добавили столбик, что бы обеспечить уникальность строки.
Натуральный первичный ключ - это когда хватает самих данных что бы обеспечить уникальность строки.
--------------------------------------------------

Когда вы указываете что такой то столбик (или столбики) должен быть первичным ключем - вы задаете правило, которое база данных будет соблюдать:
- данные в столбике будут уникальны (если ключ - это один столбик)
- совокупность данных в столбиках будут уникальны (если ключ - это два и более столбиков)

И такие ошибочные ситуации возникнуть не должны:
Код:
Дата и время        | Номер клиента | Описание заказа
--------------------+---------------+-------------------
2008-03-01 10:15:20 |      1        | Книга
2008-03-01 10:15:20 |      1        | Ручка
(неясно что клиент заказал: книгу или ручку?)

Или:
Код:
Номер заказа |Дата и время        | Номер клиента | Описание заказа
-------------+--------------------+---------------+-------------------
      1      |2008-03-01 10:15:20 |      1        | Книга
      1      |2008-03-01 10:17:30 |      1        | Ручка
(Какой заказ истинный?)

Если задать первичный ключ - такие ситуации не возникнут.
Потому что база данных выкинет ошибку.

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


-------------
"Натуральный первичный ключ", правильнее называть: "Естественный первичный ключ"
это на английском - Natural Primary Key :glasses:

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)


Последний раз редактировалось AlexShop 6 Март 2008, 05:36:28, всего редактировалось 1 раз.
SG_standard Муж.
постоянный участник
59
Сообщения: 4078
Зарегистрирован: 17.11.06
Откуда: СПб-сити
Сообщение Добавлено: 6 Март 2008, 05:26:20 
ну нифига себе, сколько всего надо знать, чтобы заказать простую ручку!

_________________
Пожуй добра!
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 6 Март 2008, 11:02:17 
AlexShop, все это замечательно, но:

1. Упущено понятие "потенциальный ключ".
2. То, что "Дата и время" и "Номер клиента" являются потенциальным ключом -- по меньшей мере не очевидно. Тяжесть фразы "не должен иметь два заказа в одну секунду" вы осознаете, когда однажды случится делать миграцию данных или интеграцию с другой системой (с другим сайтом).
3. Суррогатные включи вводят вовсе не потому, что неудобно искать по нескольким полям. Хотя в этом тоже помогает. Но только как следствие.

Кроме того, фраза пр головную боль может быть полностью раскрыта только если объяснить, что такое нормальные формы (хотя бы первые 2) и как они связаны с использованием первичных ключей.

Так что лучше, как я уже говорил, взять Дейта. Первых глав достаточно, его вообще редко дочитывают до конца.
Арт Директор Муж.
новый человек
15
Сообщения: 128
Зарегистрирован: 07.09.05
Откуда: Москва
Сообщение Добавлено: 6 Март 2008, 11:53:39 
А наличие или отсутствие первичных ключей сказывается на производительности базы данных?
Если у меня, предположим, нет первичного ключа, но есть индексы, таблицы будут с той же скоростью объединяться?

И еще вопрос... Надо ли создавать индексы на колонках, которые участвуют в условиях поиска (where) в виде "and column_name = 1"? Т.е. колонка не участвует в объединении талиц, а только определяет условия выборки.

_________________
{'L'}('J')
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 6 Март 2008, 20:54:37 
1. Обычно при добавлении primary key формируется индекс.
2. При правильно спроектированной базе индексы помогают строить объединение. При неправильно спроектированной -- не помогают.
3. Индексы на колонках, участвующих в условиях where, строят в зависимости от селективности значений. Если там 10,000 записей и в них только значения 1, 2 и 3, то от индекса не будет никакой пользы кроме вреда.
AlexShop Муж.
участник
34
Сообщения: 1866
Зарегистрирован: 17.02.04
Сообщение Добавлено: 7 Март 2008, 04:18:10 
Crazy,
спасибо за критику. :beer:
Дейта не читал. Но обязательно прочту.

При миграцию данных (в моем примере), да есть проблемы:
- если другая таблица заказов не будет иметь "Дата и время" (а другой первичный ключ).
- часы на разных серверах почти всегда не синхронизированы, поэтому "Дата и время" могут пересекаться.
- так как "Дата и время" является частью первичного ключа - изменять ее вручную (в случае чего) очень не желательно.

Потому что если я изменю первичный ключ, это значит его придется менять на всех резервных, дублирующих устройствах и архивах (что бы сохранить целостность данных).

Что бы иметь возможность свободно менять "Дата и время" - это еще один повод, что бы использовать суррогатный ключ в моем примере.
Но аргументов за и против использования того или иного ключа действительно много.

_________________
Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Crazy Муж.
Модератор
107
Сообщения: 14561
Зарегистрирован: 23.12.01
Откуда: Moscow
Сообщение Добавлено: 7 Март 2008, 10:31:12 
Это не "еще один повод", а основная причина. :)
*   Список форумов / Начинка и техника / Программирование для WWW « | » » ответить » создать топик
 Страница 1 из 1 [ Сообщений: 9 ] 
Показать сообщения за:   Поле сортировки  
Найти:
Перейти:  
Уровень доступа: Вы не можете начинать темы. Вы не можете отвечать на сообщения. Вы не можете редактировать свои сообщения. Вы не можете удалять свои сообщения. Вы не можете добавлять вложения.
cron


ООО ДеФорум
При использовании материалов сайта ссылка на DeForum.ru — обязательна.
Проект Павла Батурина ©2001-2077; // Powered by phpBB © 2013 phpBB Group
Rambler's Top100