อะไรคือแนวทางปฏิบัติที่ดีที่สุดสำหรับการใช้ GUID เป็นคีย์หลักโดยเฉพาะเกี่ยวกับประสิทธิภาพ


336

ฉันมีแอปพลิเคชันที่ใช้ GUID เป็นคีย์หลักในเกือบทุกตารางและฉันได้อ่านว่ามีปัญหาเกี่ยวกับประสิทธิภาพเมื่อใช้ GUID เป็นคีย์หลัก จริงๆแล้วฉันไม่ได้เห็นปัญหาใด ๆ แต่ฉันกำลังจะเริ่มแอปพลิเคชันใหม่และฉันยังต้องการใช้ GUID เป็นคีย์หลัก แต่ฉันคิดว่าจะใช้ Composite Primary Key (The GUID และอาจเป็นอีกเขตข้อมูลหนึ่ง .)

ฉันใช้ GUID เพราะดีและง่ายต่อการจัดการเมื่อคุณมีสภาพแวดล้อมที่แตกต่างกันเช่นฐานข้อมูล "การผลิต" "การทดสอบ" และ "dev" และสำหรับการย้ายข้อมูลระหว่างฐานข้อมูล

ฉันจะใช้ Entity Framework 4.3 และฉันต้องการกำหนด Guid ในรหัสแอปพลิเคชันก่อนที่จะแทรกลงในฐานข้อมูล (เช่นฉันไม่ต้องการให้ SQL สร้าง Guid)

แนวปฏิบัติที่ดีที่สุดสำหรับการสร้างคีย์หลักที่ใช้ GUID คืออะไรเพื่อหลีกเลี่ยงการพบว่ามีประสิทธิภาพที่เกี่ยวข้องกับวิธีการนี้


20
ไม่ควรมีปัญหา หาก PK ของคุณเป็นกลุ่มแล้วเกือบทุกแทรกมีศักยภาพที่จะทำให้เกิดการแบ่งหน้า ในรุ่นที่ทันสมัยของ SQL Server นี่คือ "แก้ไข" กับ NEWSEQUENTIALID () แต่สิ่งนี้สูญเสียประโยชน์ของการสามารถคำนวณได้ล่วงหน้า ฉันขอแนะนำให้คุณอ่าน GUID ที่อื่นเนื่องจากนี่เป็นคำถามที่กว้างเกินไปและน่าจะเรียกร้องให้มีการสู้รบทางศาสนาที่จะดำเนินต่อไปอีกหลายชั่วโมง ...
Aaron Bertrand

4
ฉันยังต้องการเพิ่มคำว่าเซิร์ฟเวอร์จะคลุมเครือในฉันต้องการที่จะกำหนด Guid บน เซิร์ฟเวอร์ ด้าน (ไม่ต้องการที่จะปล่อยให้ SQL เพื่อสร้าง GUID)
Erik Philips

คำถามนี้มีความคล้ายคลึงกับ "sql-server-guid-sort-algorithm-ทำไม" stackoverflow.com/questions/7810602/…
Clinton Ward

คำตอบ:


495

GUID อาจดูเหมือนเป็นทางเลือกที่เป็นธรรมชาติสำหรับคีย์หลักของคุณ - และถ้าคุณต้องใช้จริง ๆ คุณอาจจะโต้แย้งว่ามันใช้สำหรับคีย์หลักของตาราง สิ่งที่ฉันขอแนะนำไม่ควรทำคือใช้คอลัมน์ GUID เป็นคีย์การทำคลัสเตอร์ซึ่ง SQL Server จะทำตามค่าเริ่มต้นเว้นแต่คุณจะบอกเป็นพิเศษ

คุณต้องแยกสองประเด็นออกจากกันจริงๆ:

  1. คีย์หลักคือการสร้างตรรกะ - หนึ่งในกุญแจผู้สมัครที่ไม่ซ้ำกันและเชื่อถือได้ระบุทุกแถวในตารางของคุณ นี้ได้อะไรจริงๆ - ค่าINTเป็นGUIDสตริง - การเลือกสิ่งที่จะทำให้ความรู้สึกมากที่สุดสำหรับสถานการณ์ของคุณ

  2. ที่สำคัญการจัดกลุ่ม (คอลัมน์หรือคอลัมน์ที่กำหนด "ดัชนีคลัสเตอร์" ในตาราง) - นี้เป็นทางกายภาพสิ่งที่จัดเก็บข้อมูลที่เกี่ยวข้องและที่นี่มีขนาดเล็กที่มีความเสถียรที่เพิ่มมากขึ้นชนิดข้อมูลเป็นเลือกที่ดีที่สุดของคุณ - INTหรือBIGINTเป็นของคุณ ตัวเลือกเริ่มต้น

โดยค่าเริ่มต้นคีย์หลักในตาราง SQL Server ยังใช้เป็นคีย์การทำคลัสเตอร์ - แต่นั่นไม่จำเป็นต้องเป็นอย่างนั้น! ฉันเห็นการเพิ่มประสิทธิภาพขนาดใหญ่เป็นการส่วนตัวเมื่อแบ่งคีย์หลัก / คลัสเตอร์แบบอิง GUID ก่อนหน้านี้เป็นสองคีย์แยก - คีย์หลัก (ตรรกะ) บน GUID และคีย์การจัดกลุ่ม (การสั่งซื้อ) ในINT IDENTITY(1,1)คอลัมน์แยกต่างหาก

ในฐานะที่เป็นKimberly Tripp - ราชินีแห่งการจัดทำดัชนี - และคนอื่น ๆ ได้ระบุไว้หลายครั้งมาก - a GUIDเนื่องจากคีย์การจัดกลุ่มไม่เหมาะสมเนื่องจากเนื่องจากการสุ่มมันจะนำไปสู่การกระจายตัวของหน้าเว็บขนาดใหญ่และดัชนี

ใช่ฉันรู้ - มีnewsequentialid()อยู่ใน SQL Server 2005 และใหม่กว่า - แต่ถึงอย่างนั้นก็ไม่ได้เรียงตามลำดับอย่างแท้จริงและเต็มไปด้วยปัญหาเช่นเดียวกับGUID- เพียงเล็กน้อยน้อยเด่นชัดดังนั้น

จากนั้นก็มีอีกเรื่องที่ต้องพิจารณา: คีย์การทำคลัสเตอร์บนตารางจะถูกเพิ่มลงในแต่ละรายการในดัชนีแต่ละรายการที่ไม่ใช่คลัสเตอร์บนตารางของคุณเช่นกัน - ดังนั้นคุณต้องการทำให้แน่ใจว่ามันมีขนาดเล็กที่สุดเท่าที่จะเป็นไปได้ โดยปกติแล้วINTแถวที่มีมากกว่า 2 พันล้านแถวนั้นน่าจะเพียงพอสำหรับตารางส่วนใหญ่และเมื่อเปรียบเทียบกับGUIDคีย์การทำคลัสเตอร์คุณสามารถประหยัดพื้นที่เก็บข้อมูลได้นับร้อยเมกะไบต์บนดิสก์และในหน่วยความจำเซิร์ฟเวอร์

การคำนวณอย่างรวดเร็ว - การใช้INTกับGUIDเป็นหลักและคีย์การทำคลัสเตอร์:

  • ตารางพื้นฐานที่มี 1'000'000 แถว (3.8 MB เทียบกับ 15.26 MB)
  • 6 ดัชนีที่ไม่เป็นคลัสเตอร์ (22.89 MB เทียบกับ 91.55 MB)

รวม: 25 MB เทียบกับ 106 MB - และนั่นเป็นเพียงตารางเดียว!

อาหารสำหรับความคิดเพิ่มเติม - สิ่งที่ยอดเยี่ยมโดย Kimberly Tripp - อ่านอ่านอีกครั้งย่อย! มันเป็นพระวรสารการจัดทำดัชนีของ SQL Server จริงๆ

ป.ล. : แน่นอนถ้าคุณต้องติดต่อกับแถวสองสามร้อยหรือสองสามพัน - ข้อโต้แย้งเหล่านี้ส่วนใหญ่จะไม่ส่งผลกระทบต่อคุณมากนัก แต่ถ้าคุณได้รับในหลายสิบหรือหลายร้อยหลายพันแถวหรือคุณเริ่มต้นนับล้าน - แล้วจุดเหล่านั้นกลายเป็นสิ่งสำคัญมากและมีความสำคัญมากที่จะเข้าใจ

อัปเดต:หากคุณต้องการให้PKGUIDคอลัมน์เป็นคีย์หลักของคุณ (แต่ไม่ใช่คีย์การทำคลัสเตอร์) และอีกคอลัมน์หนึ่งMYINT( INT IDENTITY) เป็นคีย์การทำคลัสเตอร์ของคุณให้ใช้สิ่งนี้:

CREATE TABLE dbo.MyTable
(PKGUID UNIQUEIDENTIFIER NOT NULL,
 MyINT INT IDENTITY(1,1) NOT NULL,
 .... add more columns as needed ...... )

ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable
PRIMARY KEY NONCLUSTERED (PKGUID)

CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)

โดยทั่วไป: คุณเพียงแค่ต้องบอกข้อ จำกัดอย่างชัดเจนPRIMARY KEYว่ามันNONCLUSTERED(ไม่เช่นนั้นจะสร้างเป็นดัชนีคลัสเตอร์ของคุณโดยค่าเริ่มต้น) - จากนั้นคุณสร้างดัชนีที่สองที่กำหนดไว้เป็นCLUSTERED

สิ่งนี้จะใช้งานได้ - และเป็นตัวเลือกที่ถูกต้องหากคุณมีระบบที่มีอยู่ซึ่งต้องมีการ "ออกแบบใหม่" เพื่อประสิทธิภาพ สำหรับระบบใหม่ถ้าคุณเริ่มต้นจากศูนย์และคุณไม่ได้อยู่ในสถานการณ์การจำลองแบบฉันจะเลือกID INT IDENTITY(1,1)เป็นคีย์หลักกลุ่มของฉัน - มีประสิทธิภาพมากกว่าสิ่งอื่นใดเสมอ!


2
นี่คือคำตอบที่ดีสิ่งหนึ่งที่ฉันจะพูดถึงคือความสามารถในการสร้างคีย์ก่อนที่การแทรกจะมีประโยชน์บ่อยครั้ง การใช้ "newsequentialid ()" สามารถช่วยในการทำคลัสเตอร์ แต่ต้องใช้การปัดเศษไปยัง SQL เพิ่มเติม ประโยชน์อีกประการของวิธี "คีย์ตัวแทน" คือคุณสามารถสร้างรหัสใหม่ลูกค้าฝั่งโดยมีข้อกังวลเรื่องการกระจายตัวของดัชนีน้อยลง
Andrew Theken

2
วิธีที่ฉันอ่านนี้คือการมีทั้งคอลัมน์ Uniqueidentifier ที่ไม่ใช่คลัสเตอร์และคอลัมน์ int identity FK ก็ควรจะเป็น uniqueidentifier ใช่ไหม หากคุณทำเช่นนั้นจริง ๆ แล้วคุณจะใช้คอลัมน์ข้อมูลประจำตัวโดยตรงหรือไม่
pinkfloydx33

2
คำถามเล็ก ๆ น้อย ๆ ตอนนี้ควรใช้ GUID กับการเข้าร่วมหรือ int id หรือไม่ สัญชาตญาณของฉันบอกฉันว่าควรใช้ GUID แต่ฉันไม่เห็นปัญหาทางเทคนิคโดยใช้ int id ...
Nicolas Belley

3
@marc_s แต่ในสถานการณ์จำลองแบบถ้าคอลัมน์ int เป็นข้อมูลประจำตัวเราไม่ควรใช้ GUID เนื่องจากคอลัมน์ int สามารถทำซ้ำตัวเองผ่านอุปกรณ์ต่างๆได้หรือไม่
Nicolas Belley

6
@ ไทเป: ปัญหาหลักคือถ้าคุณมีคุณค่าตามธรรมชาติ - ใช่แล้วคุณสามารถใช้เป็นคีย์หลักได้ แต่ : ค่าอย่างDATETIMEเช่นไม่มีประโยชน์สำหรับคีย์การทำคลัสเตอร์เนื่องจากมีความแม่นยำ 3.33ms เท่านั้นและทำให้มีรายการที่ซ้ำกันได้ ดังนั้นในกรณีเช่นนี้คุณ* ยังคงต้องการINT IDENTITYแทนดังนั้นโดยทั่วไปฉันจะใช้มันเป็นค่าเริ่มต้นเนื่องจากประสบการณ์ที่สั่งสมมานานกว่า 20 ปีของฉันคีย์ธรรมชาติที่ใช้งานได้จริง ๆแทบจะไม่เคยมีอยู่จริงเลยจริงๆ
marc_s

51

ฉันใช้ GUID เป็น PKs มาตั้งแต่ปี 2005 ในโลกของฐานข้อมูลแบบกระจายนี่เป็นวิธีที่ดีที่สุดในการผสานข้อมูลแบบกระจาย คุณสามารถเริ่มต้นและลืมผสานตารางโดยไม่ต้องกังวลกับการจับคู่ ints ทั่วทั้งตารางที่เข้าร่วม GUIDs joins สามารถคัดลอกได้โดยไม่ต้องกังวล

นี่คือการตั้งค่าของฉันสำหรับการใช้ GUID:

  1. PK = GUID GUID นั้นจัดทำดัชนีคล้ายกับสตริงดังนั้นตารางแถวสูง (มากกว่า 50 ล้านเรคคอร์ด) อาจจำเป็นต้องมีการแบ่งพาร์ติชันตารางหรือเทคนิคการปฏิบัติงานอื่น ๆ SQL Server มีประสิทธิภาพมากขึ้นดังนั้นความกังวลเรื่องประสิทธิภาพจึงน้อยลงและน้อยลง

  2. PK Guid เป็นดัชนีแบบไม่รวมกลุ่ม ห้ามทำดัชนีคลัสเตอร์ GUID เว้นแต่จะเป็น NewSequentialID แต่ถึงอย่างนั้นการรีบูทเซิร์ฟเวอร์ก็จะทำให้เกิดการหยุดพักใหญ่ในการสั่งซื้อ

  3. เพิ่ม ClusterID Int ให้กับทุกตาราง นี่คือดัชนีกลุ่มของคุณ ... ที่สั่งซื้อตารางของคุณ

  4. การเข้าร่วม ClusterID (int) นั้นมีประสิทธิภาพมากกว่า แต่ฉันทำงานกับตารางบันทึกประมาณ 20-30 ล้านตารางดังนั้นการเข้าร่วมกับ GUID จะไม่ส่งผลกระทบต่อประสิทธิภาพอย่างเห็นได้ชัด หากคุณต้องการประสิทธิภาพสูงสุดให้ใช้แนวคิด ClusterID เป็นคีย์หลักของคุณ & เข้าร่วมใน ClusterID

นี่คือตารางอีเมลของฉัน ...

CREATE TABLE [Core].[Email] (
    [EmailID]      UNIQUEIDENTIFIER CONSTRAINT [DF_Email_EmailID] DEFAULT (newsequentialid()) NOT NULL,        
    [EmailAddress] NVARCHAR (50)    CONSTRAINT [DF_Email_EmailAddress] DEFAULT ('') NOT NULL,        
    [CreatedDate]  DATETIME         CONSTRAINT [DF_Email_CreatedDate] DEFAULT (getutcdate()) NOT NULL,      
    [ClusterID] INT NOT NULL IDENTITY,
    CONSTRAINT [PK_Email] PRIMARY KEY NonCLUSTERED ([EmailID] ASC)
);
GO

CREATE UNIQUE CLUSTERED INDEX [IX_Email_ClusterID] ON [Core].[Email] ([ClusterID])
GO

CREATE UNIQUE NONCLUSTERED INDEX [IX_Email_EmailAddress] ON [Core].[Email] ([EmailAddress] Asc)

คุณสามารถอธิบายข้อ จำกัด ของ PK_Email ได้หรือไม่ ทำไมคุณมี ... NonClustered (EmailID ASC) แทน ... Nonclustered (ClusterID ASC)
Phil

2
พนันได้เลย. สองสิ่งหลักที่เกิดขึ้นกับดัชนี: 1. คลัสเตอร์บน ClusterID - สั่งซื้อตารางของคุณบนดิสก์ (การกระจายตัวของ 0%) 2. NonClustered บน EmailID - สร้างดัชนีฟิลด์ EmailID เพื่อเร่งการค้นหา GUID ID การค้นหาเขตข้อมูล GUID จะทำงานเป็น string-ish ดังนั้นการค้นหา EmailID จะช้าลงหากไม่มีดัชนี
Robert J. Good

@ RobertJ.Good ฉันเคยเห็นวิธีการที่กล่าวถึงก่อนหน้านี้คือการเพิ่มกุญแจ int ตัวแทนเพื่อคลัสเตอร์ใน แต่ฉันไม่สามารถหาที่ใดก็ได้ที่แสดงให้เห็นถึงประสิทธิภาพที่เพิ่มขึ้นในการมีดัชนีคลัสเตอร์คีย์ตัวแทนตัวแทนโดยใช้ฮีป คุณมีลิงค์ไปยังข้อมูลมาตรฐานหรือไม่?
Dale K

1
สวัสดี @DaleBurrell ดัชนีคลัสเตอร์คือการป้องกันการกระจายตัวของตาราง ประสิทธิภาพที่เพิ่มขึ้นเกิดขึ้นเมื่อโต๊ะเติบโตตามลำดับบนดิสก์โดยมีการกระจายตัวต่ำ
Robert J. Good

@ RobertJ.Good นั่นเป็นเว็บแอปพลิเคชันหรือไม่? คุณใช้อะไรใน url / hrefs แนวทางหรือ int?
dariol

10

ฉันกำลังพัฒนาเว็บแอปพลิเคชันด้วย EF Core และนี่คือรูปแบบที่ฉันใช้:

ทุกคลาสของฉัน (ตาราง) และ int PK และ FK ฉันมีคอลัมน์เพิ่มเติมที่มีประเภท Guid (สร้างโดย c # constructor) พร้อมกับดัชนีที่ไม่ใช่คลัสเตอร์ในนั้น

ตารางการรวมทั้งหมดภายใน EF ได้รับการจัดการผ่านทางปุ่ม int ในขณะที่การเข้าถึงจากภายนอก (ตัวควบคุม) ทำได้ด้วย Guids

วิธีการแก้ปัญหานี้ช่วยให้ไม่แสดงปุ่ม int บน url แต่ทำให้รุ่นเป็นระเบียบและรวดเร็ว


มีอะไรที่คุณต้องทำเพื่อกำหนดค่าจำนวนเต็ม pK เป็นคลัสเตอร์เช่นคำอธิบายประกอบข้อมูลหรือเป็นเพียงการกำหนดค่าโดยอัตโนมัติ?
Allen Wang

ชื่อของสถานที่ให้บริการที่คุณใช้สำหรับ Guid
Trong Phan

3

หากคุณใช้ GUID เป็นคีย์หลักและสร้างดัชนีแบบกลุ่มฉันขอแนะนำให้ใช้ค่าเริ่มต้นของค่า NEWSEQUENTIALID ()


ทำไมคุณจะทำเช่นนั้น?
authenticfafa

3

ลิงค์นี้บอกว่าดีกว่าที่ฉันสามารถทำได้และช่วยในการตัดสินใจของฉัน ฉันมักจะเลือกใช้ int เป็นคีย์หลักยกเว้นว่าฉันไม่มีความต้องการเฉพาะและฉันยังปล่อยให้เซิร์ฟเวอร์ SQL สร้าง / ดูแลฟิลด์นี้โดยอัตโนมัติเว้นแต่ฉันมีเหตุผลบางอย่างที่ไม่ควรทำ ในความเป็นจริงต้องคำนึงถึงประสิทธิภาพตามแอพเฉพาะของคุณ มีหลายปัจจัยในการเล่นที่นี่รวมถึง แต่ไม่ จำกัด เฉพาะขนาดฐานข้อมูลที่คาดไว้การจัดทำดัชนีที่เหมาะสมการสืบค้นที่มีประสิทธิภาพและอื่น ๆ แม้ว่าคนอาจไม่เห็นด้วยฉันคิดว่าในหลาย ๆ สถานการณ์คุณจะไม่สังเกตเห็นความแตกต่างของตัวเลือกทั้งสองและคุณควรเลือกสิ่งที่เหมาะสมกว่าสำหรับแอพของคุณและสิ่งที่ช่วยให้คุณพัฒนาได้ง่ายขึ้นเร็วขึ้นและมีประสิทธิภาพมากขึ้น ที่เหลือทำในสิ่งที่แตกต่าง :)

https://web.archive.org/web/20120812080710/http://databases.aspfaq.com/database/what-should-i-choose-for-my-primary-key.html

ป.ล. ฉันไม่แน่ใจว่าทำไมคุณจะใช้คอมโพสิต PK หรือสิ่งที่เป็นประโยชน์ที่คุณเชื่อว่าจะให้คุณ


เห็นด้วยอย่างสิ้นเชิง!! แต่นั่นหมายความว่าถ้าฉันมี GUID เป็น PK หรือคอมโพสิต PK ที่มี GUID และสาขาอื่นจะเป็นสิ่งเดียวกัน
VAAA

1
PK (ดัชนี) จะประกอบด้วยสองคอลัมน์ แต่ถ้าคุณไม่มีเหตุผลเฉพาะทางธุรกิจสำหรับการทำเช่นนี้ดูเหมือนว่าไม่จำเป็น
แมตต์

1
BTW คำถามนี้เป็นหนึ่งในคำถามที่โพลาไรซ์และเป็นที่ถกเถียงกันมากที่สุดดังนั้นจึงเป็นเรื่องยากมากที่จะได้รับคำตอบว่าคุณจะรู้สึกสะดวกสบาย 100% วิธีการอย่างใดอย่างหนึ่งมาพร้อมกับการแลกเปลี่ยนขอให้โชคดี :)
แมตต์

1

เวลาส่วนใหญ่ไม่ควรใช้เป็นคีย์หลักสำหรับตารางเนื่องจากมีผลกระทบต่อประสิทธิภาพของฐานข้อมูลจริงๆ ลิงค์ที่มีประโยชน์เกี่ยวกับ GUID ส่งผลกระทบต่อประสิทธิภาพการทำงานและเป็นคีย์หลัก

  1. https://www.sqlskills.com/blogs/kimberly/disk-space-is-cheap/
  2. https://www.sqlskills.com/blogs/kimberly/guids-as-primary-keys-andor-the-clustering-key/

0

การมีรหัสประจำตัวทำให้การแฮ็กเกอร์หรือคนขุดแร่ข้อมูลทำได้ง่ายขึ้นมากเพื่อให้ไซต์และข้อมูลของคุณถูกโจมตี พึงระลึกไว้เสมอว่าเมื่อเลือก PK สำหรับเว็บไซต์


คุณสามารถให้เหตุผลหรือหลักฐานเพื่อสำรองข้อเรียกร้องนี้ได้หรือไม่? ฉันกำลังดิ้นรนเพื่อดูว่ารหัสต่อเนื่องอาจส่งผลต่อความปลอดภัย
jonaglon

แน่นอนว่าถ้าคุณรู้ว่าหมายเลข ID เป็นจำนวนเต็มคุณสามารถเดาระเบียนตามลำดับใน DB ดังนั้นหากคุณสอบถามรายการเดียวคุณสามารถพูดได้ว่ารายการถัดไปคือ pk + 1 หากคุณมี GUIDS แบบสุ่มรายการนั้นจะไม่เป็นไปตามรูปแบบ แทบจะเป็นไปไม่ได้เลยที่จะสืบค้นระเบียนอื่นที่ไม่ใช่แบบสอบถามที่คุณเคยถามมาก่อนหน้านี้ (และรู้จัก PK)
DaBlue

1
หากแฮกเกอร์สามารถสืบค้นฐานข้อมูลของคุณที่ถูกบุกรุกไปแล้วฉันไม่สามารถดูได้ว่า id เรียงลำดับทำให้สถานการณ์แย่ลงได้อย่างไร
jonaglon

1
หากผู้ใช้สามารถสลับออก 1012 สำหรับหมายเลขอื่นและดูข้อมูลที่พวกเขาไม่ควรจะมีปัญหาด้านความปลอดภัยที่ร้ายแรงมากปัญหานั้นไม่ได้เกิดจากตัวเลือกคีย์หลัก แต่จะทำให้รุนแรงขึ้น ฉันจะเอาประเด็นของคุณขอบคุณที่สะกดมันออกมา
jonaglon

2
คุณสามารถใช้ GUID เพื่อค้นหาระเบียนที่หน้าเว็บซึ่งไม่ใช่ PK ของตาราง การใช้พารามิเตอร์การสืบค้นในเว็บไซต์ไม่ควรกำหนดวิธีการจัดโครงสร้าง DB schema ของคุณ PK ไม่มีส่วนเกี่ยวข้องกับอินพุตและพารามิเตอร์ใน UI หรือระบบส่วนหลัง
Panos Roditakis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.