Лучший тип данных первичного ключа для Linq to SQL
Я начинаю новый проект с SqlServer и Linq to Sql. Какой тип данных будет лучше для суррогатных ключей в таблицах: identity
или же uniqueidentifier
?
Как я понял, identity
автоматически генерируется при вставке, в то время как uniqueidentifier
должен быть сгенерирован в коде (GUID).
Существуют ли существенные различия в производительности? например identity
значение должно быть прочитано после вставки, поэтому после вставки происходит дополнительное отключение базы данных.
Редактировать:
Я нашел очень подробный ответ на другой вопрос: таблицы без первичных ключей. Прочитайте выбранный ответ.
Изменить 2:
Что касается ответов о суррогатных ключах: мне нравятся суррогатные ключи больше, чем натуральные ключи. Это решение принято, поэтому, пожалуйста, не предлагайте пересмотреть структуру базы данных. Также, пожалуйста, не обсуждайте плюсы и минусы натуральных и суррогатных ключей.
6 ответов
Я согласен с комментарием, что вам следует создавать свою структуру БД независимо от метода доступа к данным. Будь то LINQ2SQL, ADO.NET или NHibernate, вы получите тот же набор преимуществ / проблем, независимо от того, является ли ваш PK идентификатором автоинкремента или GUID.
На самом деле я могу думать только об одной цели - использовать GUID в пользу INT в качестве PK - в сильно распределенном приложении с несколькими базами данных, где данные должны быть синхронизированы с главным сервером и т. Д. Даже тогда вы можете использовать IDENTITY с разными приращениями, например, IDENTITY(1,2) для одного сервера БД, IDENTITY (2, 2) для следующего и т. Д. [Конечно, работает только с фиксированным количеством серверов БД.]
Основная "проблема" с GUID заключается в том, что он занимает больше места (16 байт по сравнению с 4/8) не только как PK, но и как часть любого индекса в этой таблице, поскольку каждый индекс неявно хранит значение PK. Сравнение 16 байтов тоже будет медленнее (насколько? Вы должны его измерить, это зависит)
Кроме того, поскольку GUID являются случайными, вы можете получить много разбиений страницы при вставке строк (хотя я считаю, что в SQL Server 2005 или 2008 появилась новая функция для генерации последовательных идентификаторов GUID) в таблицу. Одно это может быть довольно дорогостоящим в среде с большим количеством вставок.
Я не думаю, что это хорошая идея, чтобы выбрать первичный ключ вашей таблицы на основе того факта, что вы используете LINQ-to-SQL. На мой взгляд, было бы намного лучше использовать первичный ключ по прямому назначению - для обеспечения целостности данных путем уникальной идентификации конкретной строки. Целочисленные или GUID PK не защищают вас от наличия дублирующихся строк в вашей таблице (кроме автоматически сгенерированных столбцов, конечно). С другой стороны, была большая дискуссия, бушующая о плюсах и минусах автоматически сгенерированных ключей:)
Либо один хорошо. Это зависит от вашего дизайна. UNIQUEIDENTIFIER будет работать, когда вам нужно создать идентификаторы на стороне клиента, что иногда может быть полезно, когда вы создаете список объектов, которые вам нужно будет добавить / удалить / изменить на клиенте перед отправкой в базу данных. Также лучше, если вам нужно объединить данные, созданные в разных системах.
INT меньше, поэтому они, вероятно, будут быстрее, и их намного проще использовать, когда вы что-то отлаживаете с вашими данными, потому что их легче обсуждать.
Короче говоря, здесь нет "лучшего" ответа. Это дизайнерское решение.
Я использую тождество и либо int, либо bigint в зависимости от ожидаемого размера таблицы. Я ожидаю, что LINQ выполняет один запрос, который объединяет вставку и чтение ключа.
uniqueidentifier
также может быть вставлен автоматически, установив значение по умолчанию в базе данных NEWID()
,
ОК, я только что написал блог об этом. Я делаю репост ниже для пользы других.
Основная суть, по-видимому, в комментариях, сделанных в блоге ado.net, в которых говорится, что Entity Framework - это единственное, что получает основное время для разработчиков для Visual Studio 2010 и Dot Net 4.
Мы знали это
Мой ответ - DUH. Мы все это знали. Microsoft публично заявила на PDC 2007, что LINQ to SQL был кратковременным выпуском для SQL Server, потому что не было никакой другой истории LINQ для SQL Server. Работает только с SQL Server. Вы не можете написать поставщика LINQ to SQL - для этого нет модели. Это была единая технология, не расширяемая.
Entity Framework = Провайдер
Entity Framework - это ЕДИНСТВЕННЫЙ путь от Microsoft по созданию поставщика LINQ. Платформа Entity Framework оказалась довольно противоречивой, но я думаю, что это отчасти связано с тем, что LINQ to SQL сегодня лучше воспринимается программистами. Entity Framework поймает и превзойдет LINQ to SQL, потому что это инструмент будущего ORM/Mapping от Microsoft.
Я думаю, что Microsoft вкладывает огромные средства в Entity Framework со сторонними поставщиками, такими как мы, IBM, Oracle и т. Д. Если они хотят, чтобы сторонние разработчики и базы данных поддерживали LINQ, им нужно было иметь модель для записи. Entity Framework - это ответ.
Я видел это в прошлом году, когда они выпустили LINQ to SQL с VS 2008, а не с EF. Они никогда не должны были выпускать закрытую реализацию чего-то с таким большим перекрытием. Я знаю, что они хотели историю с реляционной базой данных, но я думаю, что они рассказали не ту историю. Сейчас есть много серьезно запутанных разработчиков, которые спрашивают нас о нашем поставщике LINQ to SQL. Там нет ни одного, потому что вы не можете написать один.