2014-02-18 1 views
6

Я новичок в SQL, и думать о своих наборах данных реляционно, а не иерархически - это большой сдвиг для меня. Я надеюсь получить представление о производительности (как с точки зрения объема хранилища, так и скорости обработки), а также сложности дизайна использования числовых идентификаторов строк в качестве первичного ключа вместо строковых значений, которые имеют более значимый смысл.Каковы достоинства использования числовых идентификаторов строк в MySQL?

В частности, это мое положение. У меня есть одна таблица («родительская») с несколькими сотнями строк, для которой один столбец является строковым идентификатором (10-20 символов), который, по-видимому, является естественным выбором для первичного ключа таблицы. У меня есть вторая таблица («ребенок») с сотнями тысяч (или, возможно, миллионов или более) строк, где каждая строка ссылается на строку в родительской таблице (чтобы я мог создать ограничение внешнего ключа для дочерней таблицы). (На самом деле, у меня есть несколько таблиц обоих типов со сложным набором ссылок среди них, но я думаю, что это имеет смысл.)

Так что мне нужен столбец в дочерней таблице, который дает идентификатор строкам в родительская таблица. Наивно, кажется, что создать столбец как нечто вроде VARCHAR (20), чтобы ссылаться на «естественный» идентификатор в первой таблице, приведет к огромному успеху в производительности как с точки зрения пространства для хранения, так и времени запроса, и поэтому я должен включить числовой (вероятно, auto_increment) столбец id в родительской таблице и использовать его как ссылку в дочернем элементе. Но поскольку данные, которые я загружаю в MySQL, уже не имеют таких числовых идентификаторов, это означает увеличение сложности моего кода и больше возможностей для ошибок. Хуже того, так как я занимаюсь поисковым анализом данных, я могу захотеть смеяться со значениями в родительской таблице, не делая ничего с дочерней таблицей, поэтому я должен быть осторожным, чтобы случайно не разорвать отношения на удаляя строки и теряя мой числовой идентификатор (я бы, вероятно, решил это, сохранив идентификаторы в третьей таблице или что-то глупое подобное.)

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

Заранее спасибо.

+0

С правильными индексами «производительность» в значительной степени «не имеет значения» - накладные расходы являются постоянными. Таким образом, рассмотрите вопрос с точки зрения неэффективности. – user2864740

+1

Возможный дубликат [Surrogate vs. natural/business keys] (http://stackoverflow.com/questions/63090/surrogate-vs-natural-business-keys) – Mitch

+0

1) Ваш внешний ключ не обязательно должен быть на вашем первичный ключ. 2) Если у вас есть отношения «один-ко-многим» (один родитель с большим количеством детей), колонка внешнего ключа вашего ребенка _definitely_ не должна автоматически увеличиваться. 3) ограничение внешнего ключа может иметь что-то вроде RESTRICT или CASCADE, чтобы избежать случайных ошибок, в зависимости от того, что именно вы будете делать. –

ответ

8

В первую очередь я бы не беспокоился о соображениях пространства. Целочисленный ключ обычно занимает четыре байта. Varchar будет занимать от 1 до 21 байта, в зависимости от длины строки. Итак, если большинство из них всего несколько символов, ключ varchar(20) займет больше места, чем целочисленный ключ. Но не экстраординарная сумма больше.

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

Есть более серьезные причины использовать первичный ключ с автоматическим добавлением.

  1. Вы знаете, какие значения были введены в последнее время.
  2. Если появляются дубликаты (что, конечно же, не обязательно для первичного ключа), легко определить, что удалить.
  3. Если вы решили изменить «имя» одной из записей, вам не нужно обновлять все таблицы, ссылающиеся на нее.
  4. Вам не нужно беспокоиться о ведущих пробелах, пробелах и других характерных чертах.

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

0

Главное преимущество, которое вы получаете от числовых значений, что им проще индексировать. Индексирование - это процесс, который использует MySQL для упрощения поиска значения.

Обычно, если вы хотите найти значение в группе, вам нужно пройти через группу, которая ищет ваше значение. Это медленно и имеет худший случай O (n). Если вместо этого ваши данные были в хорошем, доступном для поиска формате - например, binary search tree, если их можно было найти в O (lon n), намного быстрее.

Индексирование - это процесс, который MySQL использует для подготовки данных для поиска, он генерирует деревья поиска и другие умные бобы, которые помогут быстро найти данные. Это значительно ускоряет поиск. Однако для этого необходимо сравнить значение, которое вы ищете, для различных значений «ключ», чтобы определить, больше ли ваше значение или меньше ключа.

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

0

Числовые идентификаторы строк имеют много преимуществ по сравнению с идентификатором на основе строки. Большинство из них упоминается в других ответах. 1. Один из них - индексирование. Первичные ключи по умолчанию индексируются в реляционной базе данных. Таким образом, наличие числового ключа всегда более эффективно. 2. Числовые поля хранятся намного эффективнее 2. Соединения намного быстрее с помощью цифровых клавиш. 3. Идентификатор строки может быть внешним ключом. Числовые идентификаторы компактны для хранения, что делает их эффективными 4. Я думаю, что с помощью автоинкрементируемого на первичный ключ имеет свои преимущества слишком

-Спасибо _san

2

Гордон является правильным (что не удивительно).

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

Когда вы имеете дело с десятками мегалогов или меньше, пространство для хранения в основном бесплатное. Не беспокойтесь о различии между INT и VARCHAR (20) и не беспокойтесь о стоимости дискового пространства для добавления дополнительного столбца или двух. Просто неважно, когда вы можете купить приличные терабайтные диски примерно за 100 долларов США.

INT и VARCHARS могут быть проиндексированы достаточно эффективно. Вы не увидите большой разницы во времени.

Вот что вам следует беспокоиться.

Существует одна существенная ошибка в производительности индекса, которую вы можете поразить символьными индексами. Вы хотите, чтобы столбцы, на которых вы создаете индексы должны быть объявлены NOT NULL, и вы не хотите, чтобы сделать запрос, который говорит

WHERE colm IS NULL /* slow! */ 

или

WHERE colm IS NOT NULL /* slow! */ 

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

WHERE SUBSTR(colm,1,3) = 'abc' /* slow! */ 

Еще один вопрос, который задают себе вопрос. Будете ли вы однозначно идентифицировать строки в своих вспомогательных таблицах, и если да, то как? Есть ли у них какой-то первичный ключ натурального соединения? Например, вы можете иметь эти столбцы в «дочерней» таблице.

parent  varchar(20) pk fk to parent table 
birthorder int   pk 
name   varchar(20) 

Тогда вы могли бы иметь строки, как ...

parent  birthorder  name 
    homer  1    bart 
    homer  2    lisa 
    homer  3    maggie 

Но, если вы попытаетесь вставить четвертую строку здесь, как этот

homer  1    badbart 

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

Символьные строки, содержащие цифры, смешные. Например, «2» появляется после «101». Вы должны быть в курсе этого.

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