1. Ülevaade:
Meie andmebaasi disainis on põhivõti hädavajalik ning selle disain mõjutab suurt mõju kogu andmebaasi disainile. Võrdlen automaatsete inkrementaalväljade ja Guid-väljade jõudlust, tere tulemast arutlema.
2. Sissejuhatus:
1. Isejärkuvad väljad
Isejärkuvad väljad suurenevad iga kord järjestikku, tagades, et tabeli primaarvõtmed ei korduks. Kui isekasvava välja tüübi maksimaalset väärtust ei ületata ega suurendata nullist, on see peaaegu võimatu. On väga lihtne kasutada iseinkrementaalseid välju primaarvõtmetena, tavaliselt deklareeritakse lihtsalt isekasvavad atribuudid tabeli ehitamisel.
Isejärkuvad väärtused on kõik globaalsed andmeväärtused, mida tuleb süsteemis hoida, ning väärtust suurendatakse iga kord, kui andmed sisestatakse. Samaaegses keskkonnas, kus ekvivalent genereerib unikaalse identiteedi, tuleb iga inkrementaalne väärtus lukustada ja avada selle globaalse väärtusega, et tagada inkrementi unikaalsus. See võib olla samaaegne pudelikael, mis toob kaasa mõningaid jõudlusprobleeme.
Andmete migreerimisel või importimisel võivad iseinkrementaalsed väljad dubleerida, mis on kahtlemata õudusunenägu (olen sellest juba kannatanud).
Kui tahad luua hajutatud andmebaasi, on see isejärkumise väli probleem. See on tingitud sellest, et hajutatud andmebaasis võib sama nimega tabelid erinevatest andmebaasidest olla vajalik sünkroonselt replitseerimisel. Andmebaasitabeli eneseinkrementaalne väärtus dubleerub tõenäoliselt sama tabeli eneseinkrementaalse väärtusega teises andmebaasis.
2. unikaalidentifikaatori (Guid) väli
MS SQL andmebaasides saab tabeli struktuuri luua, määrates välja tüübiks unikaalse identifikaatori, ning selle vaikimisi väärtuse saab genereerida NewID() abil, et genereerida unikaalne Guid (globaalselt unikaalne identifikaator).
Guid:指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的,其算法是通过以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字生成。其格式为:04755396-9A29-4B8C-A38D-00042C1B9028.
GUID-i eeliseks on see, et genereeritud ID on suhteliselt unikaalne, olgu see siis andmete eksportimine või samm-sammuline arendus, probleeme ei esine. Kuid ID, mille see genereerib, on suhteliselt pikk ning andmebaasi ruum on samuti hõivatud, seega pole vaja seda arvestada, kuna välise salvestuse hind langeb. Lisaks pole Guid'i lihtne meelde jätta ja selles osas pole see nii hea kui automaatsed inkrementaalväljad, mis pole programmide silumisel eriti mugav.
3. Testid:
1. Testi keskkonda
Operatsioonisüsteem: Windows Server 2003 R2 Enterprise Edition Service Pack 2
Andmebaas: MS SQL 2005
CPU:Intel(R) Pentium(R) 4 CPU 3.40GHz
Mälu: DDRII. 667 1G
Kõvaketas: WD 80G
2. Andmebaasi skriptid
- --自增量字段表
- 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
Kopeeri kood Testkood
- 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
Kopeeri kood3. Andmebaasi sisestamise test Test 1 Andmebaasi maht on: 100 üksust Näita tulemust Test 2 Andmebaasi maht on: 10 000 üksust Näita tulemust
Test 3 Andmebaasi maht on: 100 000 üksust Näita tulemust Test 4 Andmebaasi maht on: 500 000 üksust Näita tulemust 4. Loe andmed andmekogumisse Test 1 Loetud andmete hulk: 100 Näita tulemust Test 2 Loetud andmemaht: 10 000 Näita tulemust Test 3 Loetud andmete hulk: 100 000 Näita tulemust Test 4 Loetud andmete hulk: 500 000 Näita tulemust 4. Salvesta koguarvu test Testitulemused 5. Määra tingimuspäringutest 300 000. kirje päringute andmebaasis on 610 300. 4. Kokkuvõte: Guidi kasutamine peamise võtmena ei ole väga aeglane, kuid kiirem kui automaatselt kasvavate sammude kasutamine.
|