1. Overzicht:
In ons databaseontwerp is de primaire sleutel van de database essentieel, en het ontwerp van de primaire sleutel heeft een grote invloed op het ontwerp van de hele database. Ik zal de prestaties vergelijken van auto-incrementele velden en Guid-velden, welkom om te discussiëren.
2. Inleiding:
1. Zelf-incrementele velden
De zelf-incrementele velden worden elke keer sequentieel geïntroduceerd, zodat de primaire sleutels in een tabel niet worden herhaald. Tenzij de maximale waarde van het zelfverhogende veldtype wordt overschreden en vanaf nul wordt verhoogd, is dit vrijwel onmogelijk. Het is heel eenvoudig om zelf-incrementele velden als primaire sleutels te gebruiken, meestal declareer je gewoon zelf-incrementerende attributen bij het bouwen van een tabel.
Zelf-incrementele waarden zijn alle globale datawaarden die in het systeem moeten worden onderhouden, en de waarde wordt verhoogd telkens wanneer de data wordt ingevoegd. In een gelijktijdige omgeving waarin het equivalent een unieke identiteit genereert, moet elke incrementele waarde worden vergrendeld en ontgrendeld met deze globale waarde om de uniciteit van de increment te waarborgen. Dit kan een gelijktijdige bottleneck zijn die enkele prestatieproblemen met zich meebrengt.
Bij het migreren of importeren van data kunnen zelf-incrementele velden worden gedupliceerd, wat ongetwijfeld een nachtmerrie is (ik heb er al last van gehad).
Als je een gedistribueerde database wilt bouwen, is dit zelf-incrementele veld een probleem. Dit komt doordat in een gedistribueerde database tabellen met dezelfde naam uit verschillende databases mogelijk synchroon gerepliceerd moeten worden. De zelf-incrementele waarde van een databasetabel wordt waarschijnlijk gedupliceerd met de zelf-incrementele waarde van dezelfde tabel in een andere database.
2. uniek identificatieveld (Guid)
In MS SQL-databases kan de tabelstructuur worden gemaakt door het veldtype als uniqueidentifier te specificeren, en de standaardwaarde kan worden gegenereerd met NewID() om een unieke Guid (Globally Unique Identifier) te genereren.
Guid:指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的,其算法是通过以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字生成。其格式为:04755396-9A29-4B8C-A38D-00042C1B9028.
Het voordeel van GUID is dat de gegenereerde ID relatief uniek is; of het nu gaat om het exporteren van data of stapsgewijze ontwikkeling, er zullen geen problemen zijn. De ID die het genereert is echter relatief lang en de databaseruimte is ook bezet, dus dit is niet nodig om dit te overwegen nu de prijs van externe opslag daalt. Bovendien is Guid niet gemakkelijk te onthouden, en in dit opzicht is het niet zo goed als automatische incrementele velden, wat niet erg handig is bij het debuggen van programma's.
3. Testen:
1. Test de omgeving
Besturingssysteem: Windows Server 2003 R2 Enterprise Edition Service Pack 2
Database: MS SQL 2005
CPU:Intel(R) Pentium(R) 4 CPU 3.40GHz
Geheugen: DDRII. 667 1G
Harde schijf: WD 80G
2. Databasescripts
- --自增量字段表
- 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
Code kopiëren Testcode
- 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
Code kopiëren3. Database-invoegtest Test 1 Het databasevolume is: 100 items Voer het resultaat uit Test 2 Het databasevolume bestaat: 10.000 items Voer het resultaat uit
Test 3 Het databasevolume bestaat: 100.000 items Voer het resultaat uit Test 4 Het databasevolume bedraagt: 500.000 items Voer het resultaat uit 4. Lees de gegevens in de DataSet Test 1 Hoeveelheid gelezen gegevens: 100 Voer het resultaat uit Test 2 Hoeveelheid gelezen gegevens: 10.000 Voer het resultaat uit Test 3 Hoeveelheid gelezen gegevens: 100.000 Voer het resultaat uit Test 4 Hoeveelheid gelezen gegevens: 500.000 Voer het resultaat uit 4. Noteer de totaaltest Testresultaten 5. Specificeer de conditiequerytest Het 300.000ste record in de querydatabase is 610.300. 4. Samenvatting: Guid als hoofdsleutel gebruiken is niet erg traag, maar het is sneller dan het gebruik van automatische groei-incrementen.
|