1. Огляд:
У нашому дизайні бази даних первинний ключ бази даних є необхідним, і дизайн первинного ключа має великий вплив на дизайн усієї бази даних. Я порівняю продуктивність авто-інкрементальних полів і Guid-полів, запросимо обговорити.
2. Вступ:
1. Самоінкрементні поля
Самоінкрементальні поля додаються послідовно кожного разу, що гарантує, що первинні ключі в таблиці не повторюються. Якщо максимальне значення типу поля з самозбільшенням не буде перевищено і не збільшене з нуля, це майже неможливо. Дуже просто використовувати самоінкрементальні поля як первинні ключі, зазвичай просто вказувати атрибути самоінкрементування при побудові таблиці.
Самоінкрементні значення — це всі глобальні значення даних, які потрібно підтримувати в системі, і значення збільшується щоразу, коли дані вставляються. У паралельному середовищі, де еквівалент генерує унікальну ідентичність, кожне інкрементальне значення має бути заблоковане та розблоковане з цим глобальним значенням, щоб забезпечити унікальність інкременту. Це може бути паралельним вузьким місцем, що супроводжується певними проблемами продуктивності.
Під час міграції або імпорту даних можуть дублюватися самоінкрементні поля, що, без сумніву, є кошмаром (я вже страждав від цього).
Якщо ви хочете створити розподілену базу даних, ця самоінкрементальна сфера є проблемою. Це пов'язано з тим, що в розподіленій базі даних таблиці з однаковими назвами з різних баз даних можуть потребувати синхронної реплікації. Самоінкрементальне значення таблиці бази даних, ймовірно, буде дубльоване з самоінкрементним значенням тієї ж таблиці в іншій базі даних.
2. поле унікального ідентифікатора (Guid)
У базах даних MS SQL структуру таблиці можна створити, вказавши тип поля як унікальний ідентифікатор, а її значення за замовчуванням можна згенерувати за допомогою NewID() для генерації унікального Guid (Глобально унікальний ідентифікатор).
Guid:指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的,其算法是通过以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字生成。其格式为:04755396-9A29-4B8C-A38D-00042C1B9028.
Перевага GUID у тому, що згенерований ID є відносно унікальним: чи то експорт даних, чи покрокова розробка — проблем не виникне. Однак 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 як основного ключа не дуже повільно, але швидше, ніж автоматичне зростання інкрементів.
|