Bu makale makine çevirisi ayna makalesidir, orijinal makaleye geçmek için lütfen buraya tıklayın.

Görünüm: 13193|Yanıt: 0

[İpucu] Guid alanının birincil anahtarının performansını kütüphanedeki öz-artım alanı kullanarak karşılaştırın

[Bağlantıyı kopyala]
Yayınlandı 26.10.2015 09:37:04 | | | |
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
  1. --自增量字段表
  2. CREATE TABLE [dbo].[Table_Id](
  3.     [Id] [int] IDENTITY(1,1) NOT NULL,
  4.     [Value] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
  5. CONSTRAINT [PK_Table_Id] PRIMARY KEY CLUSTERED
  6. (
  7.     [Id] ASC
  8. )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
  9. ) ON [PRIMARY]

  10. GO
  11. --Guid字段表
  12. CREATE TABLE [dbo].[Table_Guid](
  13.     [Guid] [uniqueidentifier] NOT NULL CONSTRAINT [DF_Table_Guid_Guid]  DEFAULT (newid()),
  14.     [Value] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
  15. CONSTRAINT [PK_Table_Guid] PRIMARY KEY CLUSTERED
  16. (
  17.     [Guid] ASC
  18. )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
  19. ) ON [PRIMARY]

  20. GO
Kopya kodu
Test kodu
  1. 1using System;
  2.   2using System.Collections.Generic;
  3.   3using System.Text;
  4.   4using System.Data.SqlClient;
  5.   5using System.Diagnostics;
  6.   6using System.Data;
  7.   8namespace GuidTest
  8.   9{
  9.    class Program
  10.    {
  11.        string Connnection = "server=.;database=GuidTest;Integrated Security=true;";
  12.        static void Main(string[] args)
  13.        {
  14.            Program app = new Program();
  15.            int Count = 10000;
  16.            Console.WriteLine("数据记录数为{0}",Count);
  17.            //自动id增长测试;
  18.            Stopwatch WatchId = new Stopwatch();
  19.            Console.WriteLine("自动增长id测试");
  20.            Console.WriteLine("开始测试");
  21.            WatchId.Start();
  22.            Console.WriteLine("测试中");
  23. 25            app.Id_InsertTest(Count);
  24.            //app.Id_ReadToTable(Count);
  25.            //app.Id_Count();
  26. 29            //查询第300000条记录;
  27.            //app.Id_SelectById();
  28. 32            WatchId.Stop();
  29.            Console.WriteLine("时间为{0}毫秒",WatchId.ElapsedMilliseconds);
  30.            Console.WriteLine("测试结束");
  31. 36            Console.WriteLine("-----------------------------------------");
  32.            //Guid测试;
  33.            Console.WriteLine("Guid测试");
  34.            Stopwatch WatchGuid = new Stopwatch();
  35.            Console.WriteLine("开始测试");
  36.            WatchGuid.Start();
  37.            Console.WriteLine("测试中");
  38. 44            app.Guid_InsertTest(Count);
  39.            //app.Guid_ReadToTable(Count);
  40.            //app.Guid_Count();
  41. 48            //查询第300000条记录;
  42.            //app.Guid_SelectById();
  43. 51            WatchGuid.Stop();
  44.            Console.WriteLine("时间为{0}毫秒", WatchGuid.ElapsedMilliseconds);
  45.            Console.WriteLine("测试结束");
  46.            Console.Read();
  47.        }
  48. 57        /**////
  49.        /// 自动增长id测试
  50.        ///
  51.        private void Id_InsertTest(int count)
  52.        {
  53.            string InsertSql="insert into Table_Id ([Value]) values ({0})";
  54.            using (SqlConnection conn = new SqlConnection(Connnection))
  55.            {
  56.                conn.Open();
  57.                SqlCommand com = new SqlCommand();
  58.                for (int i = 0; i < count; i++)
  59.                {
  60.                    com.Connection = conn;
  61.                    com.CommandText = string.Format(InsertSql, i);
  62.                    com.ExecuteNonQuery();
  63.                }
  64.            }
  65.        }
  66. 76        /**////
  67.        /// 将数据读到Table
  68.        ///
  69.        private void Id_ReadToTable(int count)
  70.        {
  71.            string ReadSql = "select top " + count.ToString() + " * from Table_Id";
  72.            using (SqlConnection conn = new SqlConnection(Connnection))
  73.            {
  74.                SqlCommand com = new SqlCommand(ReadSql, conn);
  75.                SqlDataAdapter adapter = new SqlDataAdapter(com);
  76.                DataSet ds = new DataSet();
  77.                adapter.Fill(ds);
  78.                Console.WriteLine("数据记录数为:{0}", ds.Tables[0].Rows.Count);
  79.            }
  80.        }
  81. 92        /**////
  82.        /// 数据记录行数测试
  83.        ///
  84.        private void Id_Count()
  85.        {
  86.            string ReadSql = "select Count(*) from Table_Id";
  87.            using (SqlConnection conn = new SqlConnection(Connnection))
  88.            {
  89.                SqlCommand com = new SqlCommand(ReadSql, conn);
  90.                conn.Open();
  91.                object CountResult = com.ExecuteScalar();
  92.                conn.Close();
  93.                Console.WriteLine("数据记录数为:{0}",CountResult);
  94.            }
  95.        }
  96. 108        /**////
  97.        /// 根据id查询;
  98.        ///
  99.        private void Id_SelectById()
  100.        {
  101.            string ReadSql = "select * from Table_Id where Id="+300000;
  102.            using (SqlConnection conn = new SqlConnection(Connnection))
  103.            {
  104.                SqlCommand com = new SqlCommand(ReadSql, conn);
  105.                conn.Open();
  106.                object IdResult = com.ExecuteScalar();
  107.                Console.WriteLine("Id为{0}", IdResult);
  108.                conn.Close();
  109.            }
  110.        }
  111.       
  112.        /**////
  113.        /// Guid测试;
  114.        ///
  115.        private void Guid_InsertTest(int count)
  116.        {
  117.            string InsertSql = "insert into Table_Guid ([Value]) values ({0})";
  118.            using (SqlConnection conn = new SqlConnection(Connnection))
  119.            {
  120.                conn.Open();
  121.                SqlCommand com = new SqlCommand();
  122.                for (int i = 0; i < count; i++)
  123.                {
  124.                    com.Connection = conn;
  125.                    com.CommandText = string.Format(InsertSql, i);
  126.                    com.ExecuteNonQuery();
  127.                }
  128.            }
  129.        }
  130. 143        /**////
  131.        /// Guid格式将数据库读到Table
  132.        ///
  133.        private void Guid_ReadToTable(int count)
  134.        {
  135.            string ReadSql = "select top "+count.ToString()+" * from Table_GuID";
  136.            using (SqlConnection conn = new SqlConnection(Connnection))
  137.            {
  138.                SqlCommand com = new SqlCommand(ReadSql, conn);
  139.                SqlDataAdapter adapter = new SqlDataAdapter(com);
  140.                DataSet ds = new DataSet();
  141.                adapter.Fill(ds);
  142.                Console.WriteLine("数据记录为:{0}", ds.Tables[0].Rows.Count);
  143.            }
  144.        }
  145. 159        /**////
  146.        /// 数据记录行数测试
  147.        ///
  148.        private void Guid_Count()
  149.        {
  150.            string ReadSql = "select Count(*) from Table_Guid";
  151.            using (SqlConnection conn = new SqlConnection(Connnection))
  152.            {
  153.                SqlCommand com = new SqlCommand(ReadSql, conn);
  154.                conn.Open();
  155.                object CountResult = com.ExecuteScalar();
  156.                conn.Close();
  157.                Console.WriteLine("数据记录为:{0}", CountResult);
  158.            }
  159.        }
  160. 175        /**////
  161.        /// 根据Guid查询;
  162.        ///
  163.        private void Guid_SelectById()
  164.        {
  165.            string ReadSql = "select * from Table_Guid where Guid='C1763624-036D-4DB9-A1E4-7E16318C30DE'";
  166.            using (SqlConnection conn = new SqlConnection(Connnection))
  167.            {
  168.                SqlCommand com = new SqlCommand(ReadSql, conn);
  169.                conn.Open();
  170.                object IdResult = com.ExecuteScalar();
  171.                Console.WriteLine("Guid为{0}", IdResult);
  172.                conn.Close();
  173.            }
  174.        }
  175.    }
  176. 192}
  177. 193
Kopya kodu
3. 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ı.





Önceki:asp.net ikili Base64 içeriğini görsellere dönüştürüp yerel olarak depolayabilir
Önümüzdeki:String[3]: Size özelliğinin geçersiz boyutu 0'dır.
Feragatname:
Code Farmer Network tarafından yayımlanan tüm yazılım, programlama materyalleri veya makaleler yalnızca öğrenme ve araştırma amaçları içindir; Yukarıdaki içerik ticari veya yasa dışı amaçlarla kullanılamaz, aksi takdirde kullanıcılar tüm sonuçları ödemelidir. Bu sitedeki bilgiler internetten alınmakta olup, telif hakkı anlaşmazlıklarının bu siteyle hiçbir ilgisi yoktur. Yukarıdaki içeriği indirmeden sonraki 24 saat içinde bilgisayarınızdan tamamen silmelisiniz. Programı beğendiyseniz, lütfen orijinal yazılımı destekleyin, kayıt satın alın ve daha iyi orijinal hizmetler alın. Herhangi bir ihlal olursa, lütfen bizimle e-posta yoluyla iletişime geçin.

Mail To:help@itsvse.com