Номер VS Varchar (2) первичные ключи - PullRequest
11 голосов
/ 27 ноября 2008

Сейчас я подошел к тому моменту моего проекта, который мне нужен для проектирования моей базы данных (Oracle). Обычно для таблиц статуса и стран я не использую числовой первичный ключ, например

STATUS (max 6)
AC --> Active
DE --> Deleted

COUNTRIES (total 30)
UK --> United Kingdom
IT --> Italy
GR --> Greece

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

В основной таблице приложения будут использоваться статус и страна (более одного раза, например, страна происхождения, страна назначения), и предполагается, что в год будет добавляться 600000 строк

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

SELECT m.*,
       s.status_name,
       c.country_name
  FROM main m, status s, countries c
 WHERE m.status_cd = s.status_cd
   AND m.country_cd = c.country_cd
   AND m.status_cd = 'AC'
   AND m.country_cd = 'UK'

SELECT m.*,
       s.status_name,
       c.country_name
  FROM main m, status s, countries c
 WHERE m.status_cd = s.status_cd
   AND m.country_cd = c.country_cd
   AND m.status_cd = 1
   AND m.country_cd = 2

Пояснение:

Состояние не является двоичным («макс. 6» рядом с именем таблицы). Значения, вероятно, будут:

* active
* deleted
* draft
* send
* replaced

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

Ответы [ 4 ]

5 голосов
/ 27 ноября 2008

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

Разница в производительности между объединениями с различными типами будет незначительной, и числовой код будет, во всяком случае, медленнее, поскольку есть «больше» данных для хранения (но все это настолько мало, что это незначительно, опять же ).

Итак, действуйте с натуральными кодами. Кроме всего прочего, SQL в первом примере более понятен; «Великобритания» и «AC» имеют гораздо большее значение, чем 1 и 2.

В СУБД, отличных от Oracle, вы, вероятно, использовали бы CHAR (2) для значений состояния и кода страны. Пользователи Oracle склонны использовать VARCHAR2 для всего; Я не уверен, есть ли штраф за использование столбца CHAR (2), тем более что значения столбцов имеют фиксированную длину. (Например, в Informix поле VARCHAR (2) - поле длиной до двух символов - будет хранить 3 байта, длину (всегда 2 в вашем случае) и 2 байта данных. Напротив, CHAR (2) ) поле будет занимать всего 2 байта.)

2 голосов
/ 27 ноября 2008

Проверьте эту ссылку . Суть в том, что разница между производительностью между varchar и num невелика. Таким образом, вы должны пойти на что всегда имеет смысл для колонки. Здесь, похоже, в этом есть смысл.

0 голосов
/ 27 ноября 2008

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

0 голосов
/ 27 ноября 2008

Если 'status' является (и всегда будет?) Двоичным активным / удаленным полем, зачем вообще заниматься таблицей. Похоже, нормализация доведена до непрактичного предела.

Было бы определенно быстрее, не говоря уже о простоте, просто использовать поле tinyint (1) и записать активное / удаленное состояние как 1 или 0.

Это полностью исключает одно из ваших объединений, что должно быть хорошо.

...