PostgreSQL: определение первичного ключа в большой базе данных - PullRequest
9 голосов
/ 29 июня 2009

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

Теперь проблема в первичном ключе. Я мог бы просто установить автоматически увеличивающееся поле (тип SERIAL) и использовать его в качестве первичного ключа. Но это кажется глупым и пустой тратой дискового пространства, потому что поле не будет служить какой-либо цели, кроме как быть первичным ключом. (и поле может в конечном итоге закончиться, или нет?) И всегда есть другая проблема с производительностью: содержимое каждой новой вставленной строки необходимо проверять на наличие дубликатов. Таким образом, другое решение для первичного ключа, которое я придумал, состоит в том, чтобы вычислить хэш sha256 для содержимого + значение ссылки, а затем поместить его в новый столбец 'хэш' и использовать его в качестве первичного ключа. Две птицы с одним камнем. Конечно, проблема в том, что это хеш-коллизии. Это большая угроза?

У меня нет опыта работы с PostgreSQL и очень мало опыта работы с СУБД в целом, поэтому я был бы признателен за второе мнение перед созданием базы данных с характеристиками производительности улитки на шоссе (ужасное сравнение).

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

Ответы [ 6 ]

9 голосов
/ 02 июля 2009

Только что выполнил этот точный тест для довольно средней БД (200 ГБ +), выиграл большой сериал с большим отрывом Это было быстрее генерировать, быстрее объединять, меньше кода, меньше занимаемая площадь. Из-за того, как postgres хранит его, bigint незначителен по сравнению с обычным int. Вам не хватит места для хранения вашего контента задолго до того, как вам придется беспокоиться о переполнении bigint. Сделав вычисленный хэш против bigint - полностью замените bigint.

4 голосов
/ 29 июня 2009

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

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

PS. Подобный вопрос был задан и дан ответ здесь до .

Вот еще одна хорошая статья о теме: http://www.agiledata.org/essays/keys.html

3 голосов
/ 29 июня 2009

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

Целое число будет быстрее для соединений, чем первичный ключ строки из 64 символов. Кроме того, людям, пишущим запросы, гораздо проще иметь дело с ними.

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

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

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

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

2 голосов
/ 29 июня 2009

Некоторые предложения:

  • Дисковое хранилище 64-битного целого числа первичного ключа ничтожно мало, независимо от того, сколько у вас контента.
  • Вы никогда не столкнетесь с SHA256, и использование его в качестве уникального идентификатора - неплохая идея.

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

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

1 голос
/ 14 декабря 2011

Я бы использовал обычное 32-битное целое число в качестве первичного ключа. Я не думаю, что вы очень скоро превысите это число :-) Вся Википедия имеет около 3,5 миллионов статей ... Если бы вы писали 1000 статей в день, для достижения максимума целочисленного типа потребовалось бы почти 6000 лет.

1 голос
/ 29 июня 2009

Хэши плохие идеи для первичных ключей. Они приводят к тому, что вставки оказываются в случайном порядке в таблице, и это становится очень дорогостоящим, поскольку вещи должны быть перераспределены (хотя Postgres действительно не применяет это так, как другие). Я предлагаю последовательный первичный ключ, который может быть мелкозернистой временной меткой / временной меткой с последующим порядковым номером, позволяющим убить двух зайцев, и второй уникальный индекс, содержащий ваши хэш-коды. Помните, что вы хотите сохранить свой первичный ключ в виде небольшого (64-битного или менее) столбца.

См. Таблицу на http://en.wikipedia.org/wiki/Birthday_attack#The_mathematics, чтобы вы могли быть уверены, что столкновения не будет.

Не забудьте пылесосить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...