Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Трябва ли да проектирам таблица с първичен ключ varchar или int?

Когато избирате първичен ключ, обикновено избирате и клъстерирания ключ. Двамата често се бъркат, но трябва да разберете разликата.

Първични ключове са логично бизнес елементи. Първичният ключ се използва от вашето приложение за идентифициране на обект и дискусията за първичните ключове е до голяма степен дали да се използват естествени ключове или сурогатен ключ. Връзките влизат в много повече подробности, но основната идея е, че естествените ключове се извличат от съществуващо свойство на обект като ssn или phone number , докато сурогатните ключове нямат никакво значение по отношение на стопанския субект, като id или rowid и те обикновено са от тип IDENTITY или някакъв вид uuid. Личното ми мнение е, че сурогатните ключове са по-добри от естествените ключове и изборът трябва да бъде винаги стойности на идентичност само за локални приложения, насоки за всякакъв вид разпределени данни. Първичният ключ никога не се променя през целия живот на обекта.

Групирани ключове са ключът, който определя физическото съхранение на редовете в таблицата. Повечето пъти те се припокриват с първичния ключ (идентификатора на логическия обект), но това всъщност не се прилага, нито се изисква. Когато двете са различни, това означава, че в таблицата има неклъстериран уникален индекс, който реализира първичния ключ. Стойностите на клъстерирани ключове могат действително да се променят по време на живота на реда, което води до физически преместване на реда в таблицата на ново място. Ако трябва да отделите първичния ключ от клъстерния ключ (а понякога го правите), изборът на добър клъстерен ключ е значително по-труден от избора на първичен ключ. Има два основни фактора, които управляват вашия клъстерен ключов дизайн:

  1. Разпространеният модел на достъп до данни .
  2. Съображения за съхранение .

Модел за достъп до данни . По това разбирам начина, по който таблицата се запитва и актуализира. Не забравяйте, че групираните ключове определят действителния ред на редовете в таблицата. За определени модели на достъп някои оформления правят цялата разлика в света по отношение на скоростта на заявка или за актуализиране на едновременност:

  • текущи спрямо архивни данни. В много приложения данните, принадлежащи към текущия месец, са често достъпни, докато този от миналото е рядко достъпен. В такива случаи дизайнът на таблицата използва разделяне на таблицата по дата на транзакцията, често използвайки алгоритъм на плъзгащ се прозорец. Разделът за текущия месец се съхранява във файлова група, разположена на горещ бърз диск, архивираните стари данни се преместват във файлови групи, хоствани на по-евтино, но по-бавно съхранение. Очевидно в този случай клъстерираният ключ (дата) не е първичен ключ (идентификатор на транзакцията). Разделянето на двете се ръководи от изискванията за мащаб, тъй като оптимизаторът на заявки ще може да открие, че заявките се интересуват само от текущия дял и дори няма да разглеждат историческите.

  • Обработка в стила на FIFO опашката. В този случай таблицата има две горещи точки:опашката, където се появяват вмъквания (enqueue), и главата, където се случват изтривания (dequeue). Клъстерираният ключ трябва да вземе това предвид и да организира таблицата така, че физически да раздели местоположението на опашката и главата на диска, за да позволи едновременност между enqueue и dequeue, напр. с помощта на ключ за поръчка в опашката. В чисто опашки този клъстериран ключ е единственият ключ, тъй като в таблицата няма първичен ключ (съдържа съобщения , а не обекти ). Но повечето пъти опашката не е чиста, тя също така действа като хранилище за обектите и линията между опашката и масата е замъглено. В този случай има и първичен ключ, който не може да бъде клъстерираният ключ:обектите могат да бъдат поставени на опашка, като по този начин се променя стойността на клъстерирания ключ в реда на опашката, но те не могат да променят стойността на първичния ключ. Неуспехът да се види разделянето е основната причина, поради която опашките, подкрепени от потребителска таблица, са толкова известни, че са трудни за оправяне и са изпълнени със задънки:тъй като опашката и извеждането на опашката се случват разпръснати през таблицата, вместо да се локализират в опашката и в началото на опашката.

  • Корелирана обработка. Когато приложението е добре проектирано, то ще раздели обработката на свързани елементи между работните си нишки. Например процесорът е проектиран да има 8 работни нишки (да кажем, че да съответстват на 8-те CPU на сървъра), така че процесорите разделят данните помежду си, напр. работник 1 взема само акаунти с имена от A до E, работник 2 F до J и т.н. В такива случаи таблицата трябва действително да бъде групирана от името на акаунта (или чрез съставен ключ, който има най-лявата позиция на първата буква на името на акаунта), така че работниците да локализират своите заявки и актуализации в таблицата. Такава таблица би имала 8 различни горещи точки, около зоната, която всеки работник се концентрира в момента, но важното е те да не се припокриват (без блокиране). Този вид дизайн преобладава при високопроизводителни OLTP дизайни и при зареждания с бенчмарк TPCC, където този вид разделяне се отразява и в местоположението на паметта на страниците, заредени в буферния пул (местност NUMA), но се отклоних.

Съображения за съхранение . Групираният ключ ширина има огромни последици при съхранението на таблицата. За един ключът заема място във всяка нелистова страница на b-дървото, така че голям ключ ще заема повече място. Второ, и често по-важно, е, че клъстерираният ключ се използва като ключ за търсене от всеки неклъстериран ключ, така че всеки неклъстерираният ключ ще трябва да съхранява пълната ширина на клъстерирания ключ за всеки ред. Това е, което прави големи клъстерирани ключове като varchar(256) и води до лош избор за клъстерирани индексни ключове.
Също така изборът на ключа оказва влияние върху фрагментацията на клъстерирания индекс, понякога драстично засяга производителността.

Тези две сили понякога могат да бъдат антагонистични, моделът за достъп до данни изисква определен голям клъстериран ключ, който ще причини проблеми със съхранението. В такива случаи разбира се е необходим баланс, но няма магическа формула. Мерите и тествате, за да стигнете до сладкото място.

И така, какво правим от всичко това? Винаги започвайте с разглеждане на клъстерен ключ, който е и първичен ключ от формата entity_id IDENTITY(1,1) NOT NULL . Разделете двете и организирайте таблицата съответно (напр. разделяне по дата), когато е необходимо.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да получите произволни редове от таблица на SQL Server - SQL Server / TSQL урок, част 117

  2. Колко здрав е вашият SQL сървър? Проактивното наблюдение на бази данни е критично

  3. Вземете идентификатора на обект от неговото име в SQL Server:OBJECT_ID()

  4. Има ли безплатни инструменти за генериране на скриптове „INSERT INTO“ в MS SQL Server?

  5. SQL Server Insert, ако не съществува