Что если 2 ^ 32 просто недостаточно? - PullRequest
10 голосов
/ 01 апреля 2009

что если у вас в таблице так много записей, что 2 ^ 32 недостаточно для вашего идентификатора auto_increment за определенный период (день, неделя, месяц, ...)?
Что, если самого большого типа данных, предоставляемого MySQL, недостаточно?

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

Как я мог в MySQL (или любой другой системе) изначально получить неограниченное количество уникальных идентификаторов или хотя бы увеличить его экспоненциально?

В идеале я бы ожидал что-то вроде

> SELECT * FROM table;

+---+------+
| a |  b   |
+---+------+
| 1 |  1   |
| 1 |  2   |
| 1 |  3   |
|...| .... |
|...| .... |
| 1 | 2^32 |
| 2 |  1   |
| 2 |  2   |
+---+------+

Что экспоненциально увеличивает количество записей.

Как вы справляетесь с такими ситуациями?
Помните - для каждой записи необходимо иметь уникальный идентификатор.

Ответы [ 9 ]

16 голосов
/ 01 апреля 2009

Не кажется ли вам, что BIGINT UNSIGNED будет достаточно? Это диапазон от 0 до 18,446,744,073,709,551,615 или один год с 50,539,024,859,478,223 записей в день (365 дней в году), 2,105,792,702,478,259 записей в час, 35,096,545,041,304 записей в минуту или 584,942,417,355 в секунду.

При предполагаемых 600 записях в секунду (без чтения) вы можете записывать записи 974,904.028 лет с полной скоростью записи. Этого должно быть достаточно.

12 голосов
/ 01 апреля 2009

Вы можете использовать BIGINT для первичного ключа. Это 64-битное число по умолчанию.

Редактировать # 2: Очевидно, то, что я говорил ранее об изменении длины байта BIGINT, было неверным. BIGINT имеет фиксированный предел в 8 байт.

7 голосов
/ 01 апреля 2009

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

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

7 голосов
/ 01 апреля 2009

Просто используйте 128-битные ключи. Нет необходимости в неограниченном количестве ключей, поскольку вы очень быстро разрешаете больше строк, чем количество атомов во вселенной. (где-то около 256 бит).

5 голосов
/ 01 апреля 2009

Я бы начал с перехода на BIGINT на 2 ^ 64. GUID - это еще один вариант, но вы должны хранить их в «некоторой форме»

2 голосов
/ 01 апреля 2009

Не используйте автоинкрементный первичный ключ - используйте GUID или аналогичный - из статьи Википедии:

Хотя каждый сгенерированный GUID не гарантированно будет уникальным, общее количество уникальных ключей (2 ^ 128 или 3,4 × 10 ^ 38) настолько велика, что вероятность того же числа составляет генерируется дважды бесконечно мало маленький. Например, рассмотрим наблюдаемая вселенная, которая содержит около 5 × 1022 звезды; каждая звезда могла тогда получим 6,8 × 1015 универсально уникальных Идентификаторы GUID.

1 голос
/ 01 апреля 2009

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

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

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

0 голосов
/ 01 апреля 2009

Вы также можете использовать chars / varchars для своих ключевых столбцов и использовать GUID для своих ключей. Я не знаю, повлечет ли это снижение производительности по сравнению с целочисленными первичными ключами.

0 голосов
/ 01 апреля 2009

Я не уверен, как генерировать их автоматически в MySQL, и тогда они не обязательно будут последовательными, но я почти уверен, что вы могли бы использовать GUID и не беспокоиться о том, что они заполнены.

...