Это беспокоило меня некоторое время. В большинстве случаев, когда речь идет о хранении данных в таких структурах, как хеш-таблицы, программисты, книги и статьи, настаивают на том, что индексация элементов в указанных структурах по значениям String считается плохой практикой. Тем не менее, до сих пор я не нашел ни одного такого источника, чтобы также объяснить, ПОЧЕМУ это считается плохой практикой. Зависит ли это от языка программирования? На базовых рамках? На реализацию?
Возьмите два простых примера, если это поможет:
SQL-подобная таблица, где строки индексируются первичным ключом String.
Словарь .NET, где ключами являются строки.
username
первичный ключusers
таблицы, вероятно, не лучшая идея, и вы бы предпочли идентификатор с автоматическим приращением. Но этаusername
строка является лишь случайной, так как изменяемое свойство является главной проблемойОтветы:
Все это в основном связано с двумя вещами:
1) Скорость поиска (где целые числа, например, намного лучше)
2) Размер индексов (где взрываются строковые индексы)
Теперь все зависит от ваших потребностей и размера набора данных. Если в таблице или коллекции содержится около 10-20 элементов, тип ключа не имеет значения. Это будет очень быстро даже со строковым ключом.
PS Может не относиться к вашему вопросу, но Guids считаются плохими и для ключей базы данных (16-байтовое Guid против 4-байтового целого). На больших объемах данных Guids замедляют поиск.
источник
Есть еще одна проблема с использованием строк в качестве ключей, или, точнее, с использованием строковых литералов в качестве ключей, оставляя без внимания чисто соображения производительности / эффективности. Опечатки. Если вы используете строковые литералы в качестве ключей в словаре, вы настраиваете себя на неприятный сюрприз, когда
"ReceiverId"
становитесь"RecieverId"
. Установите константы для хранения значений ключей и используйте их каждый раз, когда вы обращаетесь к словарю.Можно сказать, что это тривиально и очевидно, но в огромном количестве примеров кода .NET в Интернете используются строковые литералы, пропагандирующие эту сомнительную практику. ASP.NET со всеми Sessions, ViewStates и QueryParams, разбросанными по базе кода, особенно виноват в этом.
источник
"1"
и"1 "
в той же таблице.Здесь есть много компромиссов. На самом деле я часто использую строковые ключи, но часто я включаю суррогатные вторичные ключи для объединений (очевидно, было бы наоборот, если бы я использовал MySQL). Однако есть случаи, когда я этого не делаю.
Во-первых, я фанат объявления естественных ключей в качестве первичного ключа, где БД может справиться с этим хорошо (например, PostgreSQL). Это помогает в нормализации и делает проект базы данных более понятным. Суррогатные ключи облегчают присоединение.
Есть две причины, по которым я обычно добавляю суррогатные ключи:
Не всегда понятно, что такое естественный ключ. Иногда они должны быть изменены. Изменение естественного составного ключа, когда он используется для объединений и ссылочной целостности, является сложным и подверженным ошибкам.
Производительность соединения на составных ключах проблематична, и как только вы идете по естественному ключу, вы застреваете там.
Однако в тех случаях, когда естественным ключом является определение, один столбец и текст, я обычно присоединяюсь к строковому ключу. Моя причина для этого состоит в том, что это часто избегает соединений при поиске. Наиболее распространенное использование - это обеспечение правильного дизайна БД вокруг варианта использования типов enum. В большинстве случаев они не требуют дополнительного объединения для обычных запросов. Так что в этом случае строковые ключи в качестве ключей соединения имеют смысл.
Например, в LedgerSMB мы храним категории учетных записей. Они идентифицируются по строковой ссылке, а некоторые другие данные хранятся со строковой ссылкой, которая используется для обеспечения соблюдения правил, касающихся комбинаций категоризаций, которые могут повлиять на учетную запись. Единственная необходимая логика - это сохранение набора категорий, поэтому мы присоединяемся к строковому ключу.
Что касается того, почему по умолчанию будут целочисленные ключи, я не думаю, что это просто вопрос размера индекса. Большой проблемой является управление ключами. Поскольку ключ произвольный, и вы можете иметь дело с миллионами записей, вы должны иметь способ генерировать уникальные строки. Есть случаи, когда для этого люди используют UUID, но существует вероятность ненулевого столкновения UUID, и там, где хранятся миллиарды записей, этот шанс становится достаточно высоким, что можно увидеть, в то время как вероятность столкновения с увеличенными целочисленными типами равна нулю. по определению.
источник
Существует множество потенциальных проблем с использованием строк в качестве ключей, особенно когда речь идет о таблицах, подобных SQL. Как упомянул @bunny, индексы для ваших таблиц будут больше, но я думаю, что более важно, любые отношения внешнего ключа к таблице будут включать ОБА таблицы, содержащие строку, а не более легкий (целочисленный) идентификатор , Если вы обнаружите, что существует еще больше таблиц со ссылками на первую, строковые ключи будут распространяться по всей вашей базе данных.
источник
Это не плохая идея сама по себе, обычно 20/20 задним числом - плохой компромисс в дизайне. Гибкость и ассортимент струн в зависимости от дополнительных затрат и сложности.
Если целое число соответствует диапазону заданий и большая часть дорогостоящей обработки не должна знать, что представляет собой целое число, используйте его.
источник
Вы каким-то образом получили неверные данные из Hashtable.
Вы имели в виду "Дневной телефон" или "Вечерний телефон"?
или
Вы имели в виду 1234567 или 1234576?
В то время как числа, возможно, более эффективны для машины , всякий раз, когда дела идут плохо (и они это делают), вам и нам самим приходится разбираться в том, что произошло, и, в этот момент, сэкономить несколько байт памяти и несколько микро (нано?) - секунд обработки теряют ясность каждый раз.
источник
Множество компромиссов и ни один правильный ответ. Многие программисты никогда бы не подумали об использовании строковых ключей в базе данных, потому что они не знают о хешировании и о том, как работает база данных. Строковые ключи, если они либо чрезвычайно стабильны, либо бессмысленны (суррогаты), являются хорошим выбором при многих обстоятельствах.
источник
строковый ключ будет иметь смысл, когда дело доходит до таблицы поиска с 10-100 короткими строковыми записями; связанные данные более читабельны + например, отслеживание изменений (числовой идентификатор / идентификатор guid по сравнению со строкой, например, «Администратор»); Кстати, база данных членства ASP.NET использует строковые ключи для AspNetRoles.
источник