Acest articol este un articol oglindă al traducerii automate, vă rugăm să faceți clic aici pentru a sări la articolul original.

Vedere: 13193|Răspunde: 0

[Bacșișuri] Comparați performanța cheii primare a câmpului Guid folosind câmpul auto-incremental din bibliotecă

[Copiază linkul]
Postat pe 26.10.2015 09:37:04 | | | |
1. Prezentare generală:

În proiectarea bazei noastre de date, cheia primară a bazei de date este esențială, iar designul acesteia are un impact major asupra designului întregii baze de date. Voi compara performanța câmpurilor auto-incrementale și câmpurilor Guy, bine ai venit să discutăm.

2. Introducere:

1. Câmpuri auto-incrementale

      Câmpurile auto-incrementale sunt incrementate secvențial de fiecare dată, asigurând că cheile primare dintr-un tabel nu sunt repetate. Dacă valoarea maximă a tipului de câmp auto-incrementant nu este depășită și incrementată de la zero, acest lucru este aproape imposibil. Este foarte simplu să folosești câmpuri auto-incrementale ca chei primare, în general doar să declari atribute auto-incrementante când construiești un tabel.

      Valorile auto-incrementale sunt toate valorile globale ale datelor care trebuie menținute în sistem, iar valoarea este incrementată de fiecare dată când datele sunt introduse. Într-un mediu concurent în care echivalentul generează o identitate unică, fiecare valoare incrementală trebuie blocată și deblocată cu această valoare globală pentru a asigura unicitatea incrementului. Acesta poate fi un blocaj concomitent care implică unele probleme de performanță.

Când migrezi sau importi date, câmpurile auto-incrementale pot fi duplicate, ceea ce este fără îndoială un coșmar (am suferit deja de asta).

      Dacă vrei să construiești o bază de date distribuită, acest câmp auto-incremental este o problemă. Acest lucru se datorează faptului că, într-o bază de date distribuită, tabelele cu același nume din baze de date diferite pot necesita replicare sincronă. Valoarea auto-incrementală a unui tabel de bază de date este probabil să fie duplicată cu valoarea auto-incrementală a aceluiași tabel într-o altă bază de date.

2. câmpul unicidentificator (Guid)

În bazele de date MS SQL, structura tabelului poate fi creată prin specificarea tipului câmpului ca unic identificator, iar valoarea sa implicită poate fi generată folosind NewID() pentru a genera un Guid unic unic (Identificator Global Unică).

Guid:指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的,其算法是通过以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字生成。其格式为:04755396-9A29-4B8C-A38D-00042C1B9028.

Avantajul GUID este că ID-ul generat este relativ unic, fie că este vorba de exportul datelor sau de dezvoltarea pas cu pas, nu vor exista probleme. Totuși, ID-ul generat este relativ lung, iar spațiul în baza de date este de asemenea ocupat, deci nu este nevoie să luăm în considerare acest lucru, deoarece prețul stocării externe scade. În plus, Guid nu este ușor de reținut și, din acest punct de vedere, nu este la fel de bun ca câmpurile incrementale automate, ceea ce nu este foarte convenabil la depanarea programelor.

3. Testare:

1. Testarea mediului

Sistem de operare: Windows Server 2003 R2 Enterprise Edition Service Pack 2

Bază de date: MS SQL 2005

CPU:Intel(R) Pentium(R) 4 CPU 3.40GHz

Memorie: DDRII. 667 1G

Hard disk: WD 80G

2. Scripturi de bază de date
  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
Cod de copiere
Cod de test
  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
Cod de copiere
3. Test de inserție în baza de date
Test 1
Volumul bazei de date este: 100 de elemente
Rulează rezultatul
Test 2
Volumul bazei de date este: 10.000 de elemente
Rulează rezultatul

Test 3
Volumul bazei de date este: 100.000 de elemente
Rulează rezultatul
Test 4
Volumul bazei de date este: 500.000 de elemente
Rulează rezultatul
4. Citește datele în DataSet
Test 1
Cantitate de date citite: 100
Rulează rezultatul
Test 2
Cantitate de date citite: 10.000
Rulează rezultatul
Test 3
Cantitate de date citite: 100.000
Rulează rezultatul
Test 4
Cantitate de date citite: 500.000
Rulează rezultatul
4. Înregistrarea testului total al numerelor
Rezultatele testelor
5. Specifică testul de interogare a condiției
A 300.000-a înregistrare din baza de date este 610.300.
4. Rezumat:
Folosirea Guid ca cheie principală nu este foarte lentă, dar este mai rapidă decât folosirea incrementilor de creștere automată.





Precedent:asp.net transformă conținutul binar Base64 în imagini și îl stochează local
Următor:String[3]: proprietatea Size are o dimensiune invalidă de 0.
Disclaimer:
Tot software-ul, materialele de programare sau articolele publicate de Code Farmer Network sunt destinate exclusiv scopurilor de învățare și cercetare; Conținutul de mai sus nu va fi folosit în scopuri comerciale sau ilegale, altfel utilizatorii vor suporta toate consecințele. Informațiile de pe acest site provin de pe Internet, iar disputele privind drepturile de autor nu au legătură cu acest site. Trebuie să ștergi complet conținutul de mai sus de pe calculatorul tău în termen de 24 de ore de la descărcare. Dacă îți place programul, te rugăm să susții software-ul autentic, să cumperi înregistrarea și să primești servicii autentice mai bune. Dacă există vreo încălcare, vă rugăm să ne contactați prin e-mail.

Mail To:help@itsvse.com