1. Обзор:
В нашем проектировании базы данных первичный ключ базы данных является необходимым, и дизайн первичного ключа оказывает значительное влияние на дизайн всей базы данных. Я сравню производительность автоинкрементальных полей и Guid-полей — добро пожаловать к обсуждению.
2. Введение:
1. Самоинкрементальные поля
Самоинкрементальные поля увеличиваются последовательно каждый раз, чтобы первичные ключи в таблице не повторялись. Если максимальное значение самоувеличивающегося поля не превышается и не увеличивается с нуля, это практически невозможно. Очень просто использовать самоинкрементальные поля в качестве первичных ключей, обычно при построении таблицы просто указывают атрибуты самоувеличения.
Самоинкрементальные значения — это все глобальные значения данных, которые необходимо поддерживать в системе, и значение увеличивается каждый раз при вставке данных. В параллельной среде, где эквивалент генерирует уникальную идентичность, каждое инкрементальное значение должно быть заблокировано и разблокировано с этим глобальным значением, чтобы обеспечить уникальность инкремента. Это может быть одновременно узким местом, связанным с проблемами производительности.
При миграции или импорте данных самоинкрементальные поля могут дублироваться, что, без сомнения, кошмар (я уже с этим сталкивался).
Если вы хотите создать распределённую базу данных, это самоинкрементальное поле — проблема. Это связано с тем, что в распределённой базе данных таблицы с одинаковым именем из разных баз данных могут потребовать синхронного репликации. Самоинкрементальное значение таблицы базы данных, скорее всего, будет дублироваться с самоинкрементальным значением той же таблицы в другой базе данных.
2. уникальное отличие (Guid) поле
В базах данных MS SQL структура таблицы может быть создана, указав тип поля как уникальный идентификатор, а её значение по умолчанию может быть сгенерировано с помощью NewID() для генерации уникального Guid (Глобально уникальный идентификатор).
Guid:指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的,其算法是通过以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字生成。其格式为:04755396-9A29-4B8C-A38D-00042C1B9028.
Преимущество GUID в том, что сгенерированный идентификатор относительно уникален: будь то экспорт данных или пошаговая разработка, проблем не возникнет. Однако генерируемый ID относительно длинный, и пространство базы данных тоже занято, поэтому учитывать это не нужно, поскольку стоимость внешнего хранилища снижается. Кроме того, Guid сложно запомнить, и в этом отношении он хуже автоматических инкрементальных полей, что не очень удобно при отладке программ.
3. Тестирование:
1. Проверьте окружающую среду
Операционная система: Windows Server 2003 R2 Enterprise Edition Service Pack 2
База данных: MS SQL 2005
CPU:Intel(R) Pentium(R) 4 CPU 3.40GHz
Память: DDRII. 667 1G
Жёсткий диск: WD 80G
2. Скрипты базы данных
- --自增量字段表
- CREATE TABLE [dbo].[Table_Id](
- [Id] [int] IDENTITY(1,1) NOT NULL,
- [Value] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
- CONSTRAINT [PK_Table_Id] PRIMARY KEY CLUSTERED
- (
- [Id] ASC
- )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
- ) ON [PRIMARY]
- GO
- --Guid字段表
- CREATE TABLE [dbo].[Table_Guid](
- [Guid] [uniqueidentifier] NOT NULL CONSTRAINT [DF_Table_Guid_Guid] DEFAULT (newid()),
- [Value] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
- CONSTRAINT [PK_Table_Guid] PRIMARY KEY CLUSTERED
- (
- [Guid] ASC
- )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
- ) ON [PRIMARY]
- GO
Копирование кода Тестовый код
- 1using System;
- 2using System.Collections.Generic;
- 3using System.Text;
- 4using System.Data.SqlClient;
- 5using System.Diagnostics;
- 6using System.Data;
- 8namespace GuidTest
- 9{
- class Program
- {
- string Connnection = "server=.;database=GuidTest;Integrated Security=true;";
- static void Main(string[] args)
- {
- Program app = new Program();
- int Count = 10000;
- Console.WriteLine("数据记录数为{0}",Count);
- //自动id增长测试;
- Stopwatch WatchId = new Stopwatch();
- Console.WriteLine("自动增长id测试");
- Console.WriteLine("开始测试");
- WatchId.Start();
- Console.WriteLine("测试中");
- 25 app.Id_InsertTest(Count);
- //app.Id_ReadToTable(Count);
- //app.Id_Count();
- 29 //查询第300000条记录;
- //app.Id_SelectById();
- 32 WatchId.Stop();
- Console.WriteLine("时间为{0}毫秒",WatchId.ElapsedMilliseconds);
- Console.WriteLine("测试结束");
- 36 Console.WriteLine("-----------------------------------------");
- //Guid测试;
- Console.WriteLine("Guid测试");
- Stopwatch WatchGuid = new Stopwatch();
- Console.WriteLine("开始测试");
- WatchGuid.Start();
- Console.WriteLine("测试中");
- 44 app.Guid_InsertTest(Count);
- //app.Guid_ReadToTable(Count);
- //app.Guid_Count();
- 48 //查询第300000条记录;
- //app.Guid_SelectById();
- 51 WatchGuid.Stop();
- Console.WriteLine("时间为{0}毫秒", WatchGuid.ElapsedMilliseconds);
- Console.WriteLine("测试结束");
- Console.Read();
- }
- 57 /**////
- /// 自动增长id测试
- ///
- private void Id_InsertTest(int count)
- {
- string InsertSql="insert into Table_Id ([Value]) values ({0})";
- using (SqlConnection conn = new SqlConnection(Connnection))
- {
- conn.Open();
- SqlCommand com = new SqlCommand();
- for (int i = 0; i < count; i++)
- {
- com.Connection = conn;
- com.CommandText = string.Format(InsertSql, i);
- com.ExecuteNonQuery();
- }
- }
- }
- 76 /**////
- /// 将数据读到Table
- ///
- private void Id_ReadToTable(int count)
- {
- string ReadSql = "select top " + count.ToString() + " * from Table_Id";
- using (SqlConnection conn = new SqlConnection(Connnection))
- {
- SqlCommand com = new SqlCommand(ReadSql, conn);
- SqlDataAdapter adapter = new SqlDataAdapter(com);
- DataSet ds = new DataSet();
- adapter.Fill(ds);
- Console.WriteLine("数据记录数为:{0}", ds.Tables[0].Rows.Count);
- }
- }
- 92 /**////
- /// 数据记录行数测试
- ///
- private void Id_Count()
- {
- string ReadSql = "select Count(*) from Table_Id";
- using (SqlConnection conn = new SqlConnection(Connnection))
- {
- SqlCommand com = new SqlCommand(ReadSql, conn);
- conn.Open();
- object CountResult = com.ExecuteScalar();
- conn.Close();
- Console.WriteLine("数据记录数为:{0}",CountResult);
- }
- }
- 108 /**////
- /// 根据id查询;
- ///
- private void Id_SelectById()
- {
- string ReadSql = "select * from Table_Id where Id="+300000;
- using (SqlConnection conn = new SqlConnection(Connnection))
- {
- SqlCommand com = new SqlCommand(ReadSql, conn);
- conn.Open();
- object IdResult = com.ExecuteScalar();
- Console.WriteLine("Id为{0}", IdResult);
- conn.Close();
- }
- }
-
- /**////
- /// Guid测试;
- ///
- private void Guid_InsertTest(int count)
- {
- string InsertSql = "insert into Table_Guid ([Value]) values ({0})";
- using (SqlConnection conn = new SqlConnection(Connnection))
- {
- conn.Open();
- SqlCommand com = new SqlCommand();
- for (int i = 0; i < count; i++)
- {
- com.Connection = conn;
- com.CommandText = string.Format(InsertSql, i);
- com.ExecuteNonQuery();
- }
- }
- }
- 143 /**////
- /// Guid格式将数据库读到Table
- ///
- private void Guid_ReadToTable(int count)
- {
- string ReadSql = "select top "+count.ToString()+" * from Table_GuID";
- using (SqlConnection conn = new SqlConnection(Connnection))
- {
- SqlCommand com = new SqlCommand(ReadSql, conn);
- SqlDataAdapter adapter = new SqlDataAdapter(com);
- DataSet ds = new DataSet();
- adapter.Fill(ds);
- Console.WriteLine("数据记录为:{0}", ds.Tables[0].Rows.Count);
- }
- }
- 159 /**////
- /// 数据记录行数测试
- ///
- private void Guid_Count()
- {
- string ReadSql = "select Count(*) from Table_Guid";
- using (SqlConnection conn = new SqlConnection(Connnection))
- {
- SqlCommand com = new SqlCommand(ReadSql, conn);
- conn.Open();
- object CountResult = com.ExecuteScalar();
- conn.Close();
- Console.WriteLine("数据记录为:{0}", CountResult);
- }
- }
- 175 /**////
- /// 根据Guid查询;
- ///
- private void Guid_SelectById()
- {
- string ReadSql = "select * from Table_Guid where Guid='C1763624-036D-4DB9-A1E4-7E16318C30DE'";
- using (SqlConnection conn = new SqlConnection(Connnection))
- {
- SqlCommand com = new SqlCommand(ReadSql, conn);
- conn.Open();
- object IdResult = com.ExecuteScalar();
- Console.WriteLine("Guid为{0}", IdResult);
- conn.Close();
- }
- }
- }
- 192}
- 193
Копирование кода3. Тест вставки базы данных Тест 1 Объём базы данных: 100 элементов Запустите результат Тест 2 Объём базы данных: 10 000 элементов Запустите результат
Тест 3 Объём базы данных: 100 000 элементов Запустите результат Тест 4 Объём базы данных: 500 000 элементов Запустите результат 4. Прочитайте данные в DataSet Тест 1 Количество прочитанных данных: 100 Запустите результат Тест 2 Количество прочитанных данных: 10 000 Запустите результат Тест 3 Количество прочитанных данных: 100 000 Запустите результат Тест 4 Количество прочитанных данных: 500 000 Запустите результат 4. Запишите общий тест на количество Результаты тестов 5. Закажите тест запроса к условию 300 000-я запись в базе запросов — 610 300. 4. Резюме: Использование Guid в качестве основного ключа не очень медленное, но быстрее, чем автоматическое увеличение инкрементов.
|