PostgreSQL: определение первичного ключа в большой базе данных

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

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

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

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

Ответы на вопрос(6)

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

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

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

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

But, it seems stupid and a waste of disc space, because the field wouldn't serve any purpose but to be a primary key.

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

 KRTac29 июн. 2009 г., 22:03
Я планирую иметь много строк в таблице. Старые строки будут удалены, но поле будет продолжать автоматически увеличивать количество строк, поэтому, когда последовательное поле достигает 2147483647, я не могу получить больше строк в таблице, даже если таблица может быть наполовину пустой.
 29 июн. 2009 г., 22:34
Вы ссылаетесь на 32-разрядное целое число со знаком. Для 64-разрядного целого числа со знаком максимальное значение составляет 9 223 372 036 854 775 807. Я сомневаюсь, что вы когда-нибудь исчерпаете это.
 29 июн. 2009 г., 22:49
Мои 2 цента: сделать первичный ключ 64-битным int и добавить еще один столбец для вашего хэша.
 29 июн. 2009 г., 22:45
Почти наверняка. Хеш в четыре раза больше размера (256 бит).
 KRTac29 июн. 2009 г., 22:44
Будет ли он быстрее, чем хеш, даже если это 64-битный int?

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

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

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

The disk storage of a 64 bit primary-key integer is negligible no matter how much content you have. You'll never collide SHA256, and using it as a unique id isn't a bad idea.

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

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

 29 июн. 2009 г., 21:37
Если вы используете SHA256 в качестве первичного ключа, разве он не должен быть неизменным? Что произойдет, если значение контент + ссылка изменится?
 29 июн. 2009 г., 22:31
Так что, если содержание меняется, вы создаете новую запись?
 KRTac29 июн. 2009 г., 22:40
Нет, я собирался сказать, что хэш будет изменен, но это было до чтения Lars & apos; ответ.
 KRTac29 июн. 2009 г., 21:50
Харви, хорошая мысль, но если бы изменить значение содержимого строки, то я бы проверил, существует ли хэш нового содержимого + ссылка уже существует. Если это так, никаких изменений не произойдет.
 30 июн. 2009 г., 18:34
Ларс делает хорошую мысль. Хотя я все еще думаю, что алгоритмически сгенерированный ключ лучше, чем последовательность, необходимость менять первичный ключ - это плохо.

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

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

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

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

 KRTac29 июн. 2009 г., 22:29
Отличный совет, и я согласен с большинством из них. Но, как я упоминал ранее, что, когда ключ суррогата достигает 2147483647? Я мог бы использовать bigserial, но что скажется на производительности?
 30 июн. 2009 г., 11:56
В этом контексте (хранение сообщений в блогах и новостных статей) я сомневаюсь, что достижение 2 ^ 31 пунктов было бы очень вероятно. Несмотря на это, если вы хотите планировать заранее, не рисковать и использовать bigserial, я бы сказал, что результативность будет минимальной, особенно по сравнению с использованием CHAR (32) в качестве PK.

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

Решение Вопроса

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

 14 дек. 2011 г., 12:43
Были ли в ваших тестах «другая проблема с производительностью: необходимо ли проверять содержимое каждой новой вставленной строки на наличие дубликатов»?

Ваш ответ на вопрос