1. Genel Bakış:
Veritabanı tasarımımızda, veritabanının birincil anahtarı esastır ve birincil anahtarın tasarımı tüm veritabanının tasarımı üzerinde büyük etkiye sahiptir. Otomatik artış alanları ile Guid alanlarının performansını karşılaştıracağım, tartışmaya hoş geldiniz.
2. Giriş:
1. Kendi kendine artan alanlar
Kendi kendine artan alanlar her seferinde ardışık olarak artırılır, böylece tablodaki birincil anahtarlar tekrarlanmaz. Kendi kendine artan alan türünün maksimum değeri sıfırdan aşılıp artırılmadıkça bu neredeyse imkansızdır. Kendi kendine artan alanları birincil anahtar olarak kullanmak çok basittir, genellikle bir tablo oluştururken kendiliğinden artan özellikleri ilan etmek yeterlidir.
Kendi kendine artan değerler, sistemde tutulması gereken tüm küresel veri değerleridir ve veri her girildiğinde değer artırılır. Eşdeğerin benzersiz bir kimlik oluşturduğu eşzamanlı bir ortamda, her artan değer bu küresel değerle kilitlenip açılmalıdır ki artışın benzersizliği sağlansın. Bu, performans sorunları da içeren eşzamanlı bir darboğaz olabilir.
Veri taşınırken veya içe aktarılırken, kendi kendine artan alanlar çoğaltılabilir, ki bu kesinlikle bir kabus (ben zaten bundan etkilendim).
Dağıtık bir veritabanı oluşturmak istiyorsanız, bu kendi kendine artan alan bir sorundur. Bunun nedeni, dağıtık bir veritabanında, farklı veritabanlarından aynı isimli tabloların eş zamanlı olarak çoğaltılması gerekebilir. Bir veritabanı tablosunun kendi kendine artan değeri, muhtemelen başka bir veritabanındaki aynı tablonun kendi kendine artım değeriyle çoğaltılır.
2. uniqueidentifier (Guid) alanı
MS SQL veritabanlarında, tablo yapısı alan tipi uniqueidentifier olarak belirlenerek oluşturulabilir ve varsayılan değeri NewID() kullanılarak benzersiz bir Guid (Küresel Benzersiz Tanımlayıcı) oluşturulabilir.
Guid:指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的,其算法是通过以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字生成。其格式为:04755396-9A29-4B8C-A38D-00042C1B9028.
GUID'nin avantajı, üretilen ID'nin nispeten benzersiz olmasıdır; ister veri dışa aktarıyor olsun, ister adım adım geliştirme yapıyor olsun, sorun yaşanmaz. Ancak, ürettiği ID nispeten uzun ve veritabanı alanı da doludur, bu yüzden harici depolama fiyatı düştüğü için bunu dikkate almaya gerek yoktur. Ayrıca, Guid'i hatırlamak kolay değildir ve bu açıdan otomatik artım alanları kadar iyi değildir, bu da programları hata ayıklama yaparken pek kullanışlı değildir.
3. Test:
1. Çevreyi test edin
İşletim sistemi: Windows Server 2003 R2 Enterprise Edition Service Pack 2
Veritabanı: MS SQL 2005
CPU:Intel(R) Pentium(R) 4 CPU 3.40GHz
Bellek: DDRII. 667 1G
Sabit disk: WD 80G
2. Veritabanı betikleri
- --自增量字段表
- 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
Kopya kodu Test kodu
- 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
Kopya kodu3. Veritabanı ekleme testi Test 1 Veritabanı hacmi: 100 öğe Sonucu çalıştırın Test 2 Veritabanı hacmi: 10.000 öğe Sonucu çalıştırın
Test 3 Veritabanı hacmi: 100.000 öğe Sonucu çalıştırın Test 4 Veritabanı hacmi: 500.000 öğe Sonucu çalıştırın 4. Verileri Veri Setine okuyun Test 1 Okunan veri sayısı: 100 Sonucu çalıştırın Test 2 Okunan veri sayısı: 10.000 Sonucu çalıştırın Test 3 Okunan veri sayısı: 100.000 Sonucu çalıştırın Test 4 Okunan veri sayısı: 500.000 Sonucu çalıştırın 4. Toplam sayı testini kaydedin Test sonuçları 5. Koşul sorgusu testini belirtin Sorgu veritabanındaki 300.000. kayıt ise 610.300'dür. 4. Özet: Guid'i ana anahtar olarak kullanmak çok yavaş değil, ancak otomatik büyüyen artışlardan daha hızlı.
|