GUIDni asosiy kalit sifatida ishlatish

I generally use auto increment IDs as Primary Keys in databases. I am trying to learn the benefits of using GUIDs. I have read this article: https://betterexplained.com/articles/the-quick-guide-to-guids/

Ushbu GUIDlarning dastur darajasida ob'ektlarni aniqlash uchun ishlatilganligini tushunaman. Ma'lumotlar bazasi darajasida asosiy kalit sifatida saqlanadi. Misol uchun, menda quyidagi sinf bor edi:

public class Person
{
public GUID ID;
public string Name;
..

//Person Methods follow
}

Men xotirada yangi shaxsni yaratmoqchi bo'lib, so'ngra Shaxsni ma'lumotlar bazasiga qo'shishni xohlayman. Buni faqat qila olamanmi?

Person p1 = new Person();
p1.ID=GUID.NewGUID();
PersonRepository.Insert(p1);

Birlamchi kalit sifatida GUID bilan millionlab va millionlab qatorlarni o'z ichiga olgan ma'lumotlar bazasi mavjudligini ayting. Bu har doim noyob bo'ladimi? GUID-ni to'g'ri tushunishim kerakmi?

Men ushbu maqolani ilgari o'qib chiqdim: http://enterprisecraftsmanship.com/2014/11/15/ma'lumotlar bazasi bilan yaratilgan-ID-lar/. GUID va tamsayılar orasida asosiy kalit sifatida baxtli muhitni tavsiya qilgandek, meni biroz chalkashtiradi.

O'zgartirish 11/06/18

Men talabalar uchun Guitarslarning intslardan ko'ra mosroq ekanligiga ishonishimga keldim. Men CQRS dan foydalanyapman va GUIDlar yanada yaxshiroq.

Ba'zi ishlab chiquvchilar GUID-ni domen modelidagi satrlar sifatida, misol uchun. bu erda: https://github.com/dotnet-architecture/eShopOnContainers/blob/dev/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs - bu holatda: IdentityGuid - GUID modeli bir mag'lubiyat. Bu erda aytilganlardan boshqasini qilish uchun asoslar bormi? Maxsus qiymat obyektini yoki taqsimlangan tizimda identifikator sifatida identifikator sifatida foydalaning? . GUIDni mag'lubiyatga o'xshatish uchun "normal" bo'ladimi yoki model va ma'lumotlar bazasida GUID sifatida modellashtirishim kerakmi?

31
Guidlar mening talablarimga ko'ra intslardan ko'ra mosroq ekanligiga ishonishdi. Men GUID oxirgi yechim (va bu uchun int) deb aytaman. Kataloglashtirishda so'rovlarda befoyda va sirli, eng yaxshi. OTOH, tarkibiy kalitlar DSL-ish bo'lib, foydalanishda, kontekstual, tavsifga ega, moslashuvchan va ishlash uchun muhim. Murakkab PK ning pastki to'plamidagi so'rovlar uni ishlatishi mumkin. Men o'zim uchun PKni yaratishdan ehtiyot bo'laman - bu erda hech kim kafolatlanmagan. PK-bo'lmagan jadvallarda kerak bo'lganda indeks bilan noto'g'ri narsa yo'q. PKlar ma'lumotlar strukturasini, aloqalarini va talablarini o'z-o'zidan bog'laydi.
qo'shib qo'ydi muallif jbu, manba
Hozirda men ishlayotgan tizim UUID dan foydalanadi. Yaxshi xususiyat, identifikatsiya qilish ushbu jadvaldagi yozuvni identifikatsiya qiluvchi ketma-ket IDga qarama-qarshidir.
qo'shib qo'ydi muallif Bakhtiyor, manba
@ w0051977 ular yo'q, lekin yordam berishi mumkin - RoleId kodi UserRoleId kodi sifatida noto'g'ri ishlatilgan tizimlarni ko'rdim (shubhasiz, yomon kodlangan) har ikkala holatda ham ID kodi <1 kodi ishlaganligi sababli ishlaydi. UUID bilan identifikatorlar boshqacha bo'ladi.
qo'shib qo'ydi muallif Bakhtiyor, manba
UUID va boshqalar integer mumkin bo'lgan dublikati
qo'shib qo'ydi muallif gnat, manba
Shuningdek qarang: UUID to'qnashishi
qo'shib qo'ydi muallif gnat, manba
qo'shib qo'ydi muallif Euphoric, manba
Shuningdek qarang: uchun eng yaxshi variant bo'lgan "title =" uniqueidentifier va boshqalar ID va materiallar kodi ", shuningdek, ko'plab boshqa savollar - tez-tez javob berdi va tez-tez bahslashdi.
qo'shib qo'ydi muallif Arash, manba
Noyob bo'lishi kafolatlanmagan, garchi siz hech qachon to'qnashuvni ko'rmasangiz. stackoverflow.com/questions/1155008/how-unique- is-uuid// hellip;
qo'shib qo'ydi muallif icirellik, manba
@Justin, nima uchun yozuvlar bir nechta noyob jadvallar bo'lishi kerak?
qo'shib qo'ydi muallif w0051977, manba

10 javoblar

GUIDlar "global noyob identifikator" atamasi bilan belgilangan. Java-da "Umumjahon noyob identifikator" deb nomlangan Java-da o'xshash, lekin biroz boshqacha tushuncha mavjud. Nomlar barcha amaliy foydalanish uchun bir-birining o'rnini bosadi.

GUID-lar, Microsoft korporatsiyasi ma'lumotlar bazasini kriptografik ishlashning qanday ishlashini ko'zda tutadi va ba'zan bog'liq bo'lgan manbalardan ma'lumotlarni kiritish kerak bo'lsa, ular ma'lumotlar to'qnashuvining oldini olishga yordam beradi.

Ba'zi Pro-GUID faktlar:

  • GUID-lar kalitlarning to'qnashuviga yo'l qo'ymaydi.
  • GUID-lar tarmoqlar, mashinalar va boshqalar o'rtasida ma'lumotlarni birlashtirishga yordam beradi.
  • SQL Server indeksdagi bo'linishni kamaytirishga yordam beruvchi yarim-davriy GUIDlar uchun qo'llab-quvvatlaydi ( ref , ba'zi ogohlantirishlar)

GUID bilan ba'zi xunuklik

  • Ular katta, har biri 16 bayt
  • Ular buyurtma berishmaydi, shuning uchun identifikatorda tartibini o'zgartira olmaysiz va avtoto'ldirish identifikatorlari kabi qo'shimcha tartibni olishni xohlaysiz
  • Ular, ayniqsa kichik ma'lumotlar silsilasida (jadvallarni qidirish kabi) ishlashi qiyinroq bo'ladi.
  • Yangi GUID ilovasi SQL Serverda C# kutubxonasidan yaxshiroq (SQL Serverda navbatdagi GUIDlar bo'lishi mumkin, C# da tasodifiy)

Guidelar sizning katalogingizni yanada kattaroq qiladi, shuning uchun ustunni indekslashtirishning disk maydoni ancha yuqori bo'ladi. Tasodifiy GUID indekslarni qismlarga ajratadi.

Agar siz turli tarmoqlardagi ma'lumotlarni sinxronlashni rejalashtirayotganingizni bilsangiz, GUIDlar qiymatga nisbatan ko'proq yuk ko'tarishi mumkin.

Ba'zan bog'langan mijozlardan ma'lumotni qabul qilishingiz kerak bo'lsa, ular mijozlar uchun ketma-ketlik oralig'ini belgilashdan ko'ra, kalitlarning to'qnashuvining oldini olish uchun ancha mustahkam bo'lishi mumkin.

39
qo'shib qo'ydi
Men bu jamoani WIKI-ni yaratdim va eng munozarali bayonotlarni olib tashladim. Unda bor va unga eng to'g'ri javob ber. Men to'g'ri yo'ldan ketayotganimni his qilyapman, lekin uni bir nechta asosiy nuqtada qoldirgan edim.
qo'shib qo'ydi muallif tim_yates, manba
Menga aynan qandaydir javob qaytarganingiz uchun rahmat. Men bir nechta narsalarni bilib oldim.
qo'shib qo'ydi muallif tim_yates, manba
Shuningdek, ushbu ma'lumot ham yordam berishi mumkin: blog.codinghorror.com/primary -keys-id-versus-guidslar (Sizda SQL Serverda ketma-ket GUID-lar mavjud bo'lib, u har bir mashina uchun navbatdagi)
qo'shib qo'ydi muallif tim_yates, manba
Quyida ba'zi ma'lumotlar mavjud: blogs.msdn.microsoft .com/sqlserverfaq/2010/05/27/"hellip; GUID bilan bog'liq ayrim ma'lumotlarimni tan olaman va SQL Server kümeleme eski. Ba'zi narsalar o'zgaradi va ba'zi narsalar bir xil bo'ladi (masalan, SQL Server so'nggi bir necha yil ichida ishdan chiqish klasterini qo'llab-quvvatlaydi)
qo'shib qo'ydi muallif tim_yates, manba
@JimmyJames, SQL Server uchun yorlig'i bo'lganligi sababli men bunga javob berdim. Oracle GUID yoki UUID atrofida hech qachon qurilgani yo'q, shuning uchun o'z tajribamdan hayratlanaman.
qo'shib qo'ydi muallif tim_yates, manba
"Ular buyurtma qilishmaydi, shuning uchun siz identifikatorda tartiblashingiz mumkin emas va siz avtomatik ravishda idishlarni avtomatik ravishda ko'tarishingiz kabi qo'shimcha tartibni olishni umid qilaman" Shubhasiz, men muntazam kimlar bilan ham bunga tayanmayman. Keyinchalik pastki diapazonda diskka o'tishi uchun o'ta chekkada ishlov berish mumkin bo'lsa-da, menga foydali tartiblash ma'lumotlariga tayanib qo'yishni xohlayman. Idlar xotira manzillari kabi muomalada bo'lishi kerak - har bir narsaning o'zi bor, ammo qiymat o'zi ma'nosiz. Ulardan eng ko'p foydalanadigan futbolchilar uchun foydalaning. Ayniqsa, agar sizda katta yuk bor bo'lsa, qo'shimcha buyurtma berish kafolatlanmaydi.
qo'shib qo'ydi muallif Hao Sun, manba
@MaxVernon "Optimal emas" - bu katta ahamiyatga ega.
qo'shib qo'ydi muallif Andy, manba
"SQL Server GUID bilan ishlash uchun optimallashlarga ega, shuning uchun so'rovlar ishlashiga juda ta'sir qilmasligi kerak." -1 Etarlicha optimallashtirilmagan. Men barcha PK larning yo'l-yo'rig'i va yomon ishlashning asosiy sabablaridan biri bo'lgan JB bilan ishlayapman.
qo'shib qo'ydi muallif Andy, manba
"SQL Server GUID bilan ishlash uchun optimallashlarga ega, shuning uchun u ko'pincha so'rov natijalariga ta'sir qilmasligi kerak. " To'g'ri emas. Ushbu bayonotda boshqa ma'lumotlar turlari optimallashtirilmaganligini ta'kidlaydi. Ma'lumotlar bazasi serverlari, masalan, oddiy int qiymatlari bilan ishlash uchun optimallashlarga ega. GUID/UUID 4 byte int qiymatidan foydalanishga nisbatan ancha sekin. 16 bayt, hech qachon 4 bayta qadar tez bo'lmaydi - ayniqsa, eng ko'p 4 yoki 8 bayttan ishlaydigan mashinada.
qo'shib qo'ydi muallif user192127, manba
qo'shib qo'ydi muallif JimmyJames, manba
@CortAmmon Wikipedia va RFC 4122 , ular sinxronlashtiriladi. Microsoftning P. Leach, QRK yaratuvchilardan biri edi. Menimcha, QRK yaratilganidan bu ikkisi bir xil. QRMdan: "UUID (universal noyob identifikator), shuningdek GUID (universal identifikator) deb ham ataladi." Menimcha, GUIDlar MS tomonidan yaratilmagan. Ular boshqa joydan olingan texnologiya uchun yangi nom yaratdilar.
qo'shib qo'ydi muallif JimmyJames, manba
@MartinSmith Menimcha, nuqta, Jadvaldagi ichki identifikator GUID. Oracle uchun ham xuddi shunday, lekin ishonchim komilki, JK har qanday tekshiruvda uni ishlatishi kerak.
qo'shib qo'ydi muallif JimmyJames, manba
@MartinSmith Bu mening tajribamning tashqarisida, biroq, UUID vikipediyasi sahifasida nimadir bor muvofiq.
qo'shib qo'ydi muallif JimmyJames, manba
@MartinSmith Bu foydali ma'lumot, lekin men bu erda muxlislar emasman.
qo'shib qo'ydi muallif JimmyJames, manba
Menimcha, GUIDlar UUID bilan sinxronlashtirilgan. UUID - bu standart nom. GUID Microsoft ularni RFC 4122 dan oldin yaratdi.
qo'shib qo'ydi muallif JimmyJames, manba
Yo, men faqat bu bilan qanday kelishuvlar bo'lishi mumkinligini yaxshi tushunish yaxshi fikr ekanligini aytmoqchiman. Siz bir necha kishini eslatib o'tdingizmi, men buni keng qamrovli yoki yo'qligini bilmayman. Bizning holatimizda biz "native" qatori identifikatorlarini PK sifatida ishlatgan edik. Shunday qilib, men Oracle buni yaxshi ishlamayotganiga rozi ekanman, aslida bu "atrofida" qurilgan. Bu 128 bit, shuning uchun hech bo'lmaganda, 2017 yilda siz JBga bir kalit uchun bir nechta ro'yxatga olishni majbur qilasiz.
qo'shib qo'ydi muallif JimmyJames, manba
+1 va men JB bunlarni qanday ishlov berish haqida nozik bosimni o'qishni tavsiya etaman. Biz buni Oracle'da qildik va u juda yomon ketdi. Indeksni urish uchun so'rovlar qorong'u tarzda tweaked kerak edi. Muammo bo'lgan boshqa narsa (IIRC), xuddi shu mashinada bir vaqtning o'zida ishlab chiqarilgan GUIDlarning boshida va oxirida bir-biriga o'xshash, biroq o'rtada turlicha bo'lishidir, shuning uchun ushbu vaziyatni boshqarish uchun maxsus indeks yaratish strategiyasi kerak. juda katta potentsial oralig'i.
qo'shib qo'ydi muallif JimmyJames, manba
@MaxVernon shuki, ba'zilar uylar + GUID kombinatsiyasini taklif qiladimi?
qo'shib qo'ydi muallif Mark Maruska, manba
@ ypercubeᵀᴹ - Menimcha, bu jadvalni parchalash muammosini "aylanib o'tish" ning bir usuli. Garchi, bu faqat bir muammo uchun boshqasiga sotilishi mumkin edi. Tez-tez siz ularni TRUNCATE TABLE dan foydalanishingiz mumkin bo'lmaguncha, ular yaxshi emas.
qo'shib qo'ydi muallif Geocode.Farm Staff, manba
Agar ayol Tripp buni to'g'ri deb hisoblasa, u butunlay rost.
qo'shib qo'ydi muallif Geocode.Farm Staff, manba
Men GUID va UUID orasida qanday farq borligini bilaman. Bu kabi javoblar shuni tavsiya qiladiki, sinonimiy ravishda, lekin Stack Exchange - bu aniq ma'lumot /ducks dan juda uzoqdir
qo'shib qo'ydi muallif Cort Ammon, manba
GUID va UUID sinonimga aylandi. Ularni boshqacha davolash uchun harakat qilish, odamlarni yo'ldan ko'proq yo'ldan urishdir.
qo'shib qo'ydi muallif icirellik, manba

Bu har doim noyob bo'ladimi?

Always? no, not always; it's a finite sequence of bits.

Birlamchi kalit sifatida GUID bilan millionlab va millionlab qatorlarni o'z ichiga olgan ma'lumotlar bazasi mavjudligini ayting.

Millionlab va millionlab odamlar, ehtimol, sizning xavfsizligingiz. Bir million million va nosozliklarni oldini olish uchun to'qnashuv ehtimoli ahamiyatga ega. Yaxshi xabarlar bor, ammo: diskda bo'sh joyni allaqachon sodir bo'ladigan vaqtgacha ishlatasiz.

Buni faqat qila olamanmi?

Siz .. qila olasiz; siz ... mumkin; bu butunlay yaxshi fikr emas. Sizning domeningiz odatda tasodifiy sonlarni ishlab chiqmasligi kerak; ular sizning modelingiz uchun kirish bo'lishi kerak.

Bundan tashqari, ishonchsiz tarmoq bilan ishlayotganingizda, siz ikki nusxadagi xabarlarni olishingiz mumkin bo'lgan joyda deterministik ravishda yaratilgan UUID sizni ikki nusxadagi ob'ektlardan himoya qiladi. Ammo har bir yangi tasodifiy raqamni belgilasangiz, takrorlashni aniqlash uchun ko'proq ishingiz bor.

See the description of name-based uuid in RFC 4122

GUIDni mag'lubiyatga moslash uchun "normal" bo'ladimi yoki modeli va ma'lumotlar bazasida GUID sifatida modellashtirishim kerakmi?

Bu juda muhim deb o'ylamayman. Domen modelingizning ko'pchiligi uchun identifikatori ; siz so'ragan yagona so'rov boshqa identifikator bilan bir xil bo'ladimi-yo'qmi. Domeningiz modeli odatda identifikatorning xotirada bo'lishiga qaramaydi.

Agar GUID domeningizda agnostik rejimda "ibtidoiy turi" sifatida mavjud bo'lsa, men uni ishlataman; qo'llab-quvvatlovchi kontekst mavjud bo'lgan optimallashtirishni tanlashga imkon beradi.

Shuni ta'kidlash kerakki, identifikatorning xotirada va xotirada taqdim etilishi sizning amalga oshirishingizda hal qiladigan qarordir va shuning uchun siz kodning oyoq bosimini shu bilan bog'langanligini ta'minlash uchun choralar ko'rishingiz kerak. qaror kichik - qarang Parnas 1972 .

25
qo'shib qo'ydi
Bir million million = 2 ^ 40. Bu esa, mumkin bo'lgan to'qnashuvni 2 ^ 79 juftni tashkil qiladi. GUID 2 ^ 128 bitga ega, shuning uchun imkoniyat 2 ^ 49 da. Ikki yozuv uchun bir GUIDni qayta ishlatadigan xatolik yoki xato bo'lmasa, u erda hech qanday to'qnashuv mavjud emasligiga ishonasiz.
qo'shib qo'ydi muallif gnasher729, manba
Haqiqatan ham, boshqa ma'lumotlar asosida UUID/GUIDni qayta hisoblash imkoniyatiga ega bo'lish juda katta yordamdir, ayniqsa dublikatlarni aniqlash uchun. Bir vaqtlar xabarlarni saqlaydigan va ularni qayta ishlash quvurlari orqali itargan xabarlarni qayta ishlash tizimini qurdim. Men xabarning xashini yaratdim va bu tizimda asosiy kalit sifatida foydalanar edim. shunchaki, o'zim va o'zim, men tashqariga chiqib ketishimiz kerak bo'lgan xabarni aniqlash uchun ko'p masalalarni hal qilib qo'ydik.
qo'shib qo'ydi muallif Newtopian, manba
" deterministik tarzda yaratilgan UUID " tushunchasi muhim (Data Vault 2-ga qarang)
qo'shib qo'ydi muallif peterd, manba
Ehtimol, ushbu ishlab chiquvchilar o'zlarining savdosini turli darajadagi optimallashtirishga muhtoj edilar.
qo'shib qo'ydi muallif VoiceOfUnreason, manba
Rahmat. Shu sababli men aniqman. javob domen modelidagi GUID (C #) va ma'lumotlar bazasida (SQL Server) noyob identifikator (varchar so'zidan ko'ra) taklif qiladi. Shuni e'tiborga olish kerakki, bu yerda mavjud bo'lgan narsalardan farqli: "https://github.com/dotnet-architecture/eShopOnContainers/blob/dev/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs c/"hellip;
qo'shib qo'ydi muallif w0051977, manba
Men o'zimning tarixiy savollarimdan foydalanib qaytaman. Men qabul qilmasimdan oldin; O'zgartirishimga e'tibor bera olasizmi?
qo'shib qo'ydi muallif w0051977, manba
+1 uchun "siz diskda bo'sh joyni allaqachon sodir bo'lguncha ishlatasiz."
qo'shib qo'ydi muallif w0051977, manba

GUID yoki UUID ehtimol noyob ular qanday yaratilganligi va markaziy hokimiyat bilan bog'lanish kerak bo'lmasdan yagona xususiyatni kafolatlash uchun xavfsiz usulni ta'minlaydi.

GUIDlarning asosiy kalit sifatida foydalari:

  • Klasterning turli shardoshlari orasidagi ma'lumotlar nusxa ko'chirish va PK to'qnashuvlari haqida xavotirlanishga hojat yo'q.
  • Siz biron bir yozuvni joylashtirmasingizdan oldin asosiy kalitingizni bilishga imkon beradi.
  • Bola yozuvlarini kiritish uchun operatsiya mantiqini soddalashtiradi.
  • osonlik bilan taxmin qilinmaydi.

Siz bergan misolda:

Person p1 = new Person();
p1.ID = GUID.NewGUID();
PersonRepository.Insert(p1);

Qo'shib qo'yish vaqtidan oldin GUIDni belgilash ketma-ketlikdagi bola yozuvlarini kiritishda ma'lumotlar bazasiga aylantirilishi va ularni bir xil operatsiyalarda bajarishga imkon berishi mumkin.

Person p2 = new Person();
p2.ParentID = p1.ID
PersonRepository.Insert(p2);

Birinchi kalit sifatida GUIDlarga zarar yetkazish:

  • Ular katta 16 bayt, ya'ni ular indekslar va xorijiy kalitlar qo'shilsa, ko'proq joy egallaydi.
  • Ular asosan tasodifiy sonlar bo'lgani kabi, yaxshi tartiblashmaydi.
  • Indeks foydalanish juda ko'p, juda yomon.
  • Barglarning harakatlanishi ko'p.
  • Ular eslash qiyin.
  • Ular og'zaki so'zlarni aytish qiyin.
  • URLni o'qishni osonlashtiradi.

Sizning arizangizni sharding yoki kümelenmeye kerak bo'lmasa, int yoki bigint kabi kichikroq, sodda ma'lumotlar turlari bilan eng yaxshi bo'lar edi.

Ko'pgina ma'lumotlar bazalari GUID va SQL Server tomonidan yuzaga kelgan saqlash muammolarini yumshatishga urinadigan o'z ichki dasturlariga ega, hatto newsequentialid va ular odatda yaxshi ishlash ko'rsatkichlariga ega.

Bunga qo'shimcha ravishda, dastur bilan ishlaydigan tester, foydalanuvchi yoki ishlab chiquvchi nuqtai nazari bilan GUID orqali identifikatordan foydalanish kommunikatsiyani sezilarli darajada yaxshilaydi. Telefon orqali GUIDni o'qish kerakligini tasavvur qiling.

Oxir-oqibat, katta miqyosdagi kümeleme yoki obro'sini to'suvchi URL-lar talabga ega bo'lmasa, bu avtoto'ldirish identifikatorlari bilan yopishtirish uchun yanada pragmatikdir.

10
qo'shib qo'ydi
@mirabilos Fonning bahs-munozarasi, bir nechta tipdagi "Hi-Lo" algoritmidan foydalansa, IMHO oddiyroq yechim bo'ladi va siz hali ham kichikroq va asosan navbatdagi identifikatorlarni olasiz.
qo'shib qo'ydi muallif David Nehme, manba
@mirabilos Shuningdek, Oracle'da 128 bitli kalitlarni ishlatishni tavsiya etmayman. Berinning javobi haqida mening sharhimni qarang. Oracle'dagi bunday PK-lar atrofida ishlash siz uchun maxsus imtiyozlar yaratmasangiz qo'rqinchli bo'lishi mumkin.
qo'shib qo'ydi muallif JimmyJames, manba
@mirabilos Men ketma-ket blok hajmini oshirib, qanday qilib/qachon bu hal qilinmasligini tushunishga qiziqaman.
qo'shib qo'ydi muallif JimmyJames, manba
Balki men noto'g'ri tushundim. Men "URLni o'qishni qiyinlashtirishi mumkin", deb taxmin qildim. U erda ishlatilishini bildirgan. Umuman olganda, URI-dagi kalitni ishlatish odatda muammoni hal qilishi mumkinligiga amin emasman, ammo aniq bo'lishi mumkin.
qo'shib qo'ydi muallif JimmyJames, manba
@mirabilos Tushundiki, men qo'rqinchli gaplar aytayotganimizda, ketma-ket daqiqalar ni olgan qo'shimchalar bilan yakunlandik. U OKdan boshlandi, lekin minglab qatorlar 10 dan oshganidan so'ng, u tezda yonma-yon yugurdi. Agar bu aniq bo'lmasa, minglab qatorlar 10-sonli juda kichik stoldir.
qo'shib qo'ydi muallif JimmyJames, manba
Ko'rib chiqilishi kerak bo'lgan narsa shundaki, UUID turiga qarab, ular potentsial bo'lishi mumkin bo'lgan ma'lumotlarni o'z ichiga oladi. ular ishlab chiqarilgan mashinani aniqlash uchun ishlatiladi. Sof tasodifiy variant etarlicha entropiya holda to'qnashishi mumkin. Buni URIda foydalanishdan oldin ko'rib chiqish kerak.
qo'shib qo'ydi muallif JimmyJames, manba
Ulardan foydalanishning asosiy sababi, sizning kümelenmiş indeks kalitingiz sifatida GUIDga ega bo'lish, qattiq diskratsiyaga olib keladi, bu erda ketma-ket GUID bo'lmaydi. Bu, ba'zi bir xavfsizlik afzalliklari bilan bir qatorda, taxmin qilinadigan kabi ba'zi xavfsizlik tuzatishlar bilan birga keladi.
qo'shib qo'ydi muallif icirellik, manba
Birinchidan, URLdagi kalit kalitini hech qachon oshkor qilmaslik kerak. Tashqi tizimdan xavfsiz ma'lumotlar yo'qligiga ishonch hosil qilish uchun yana bir mos usulni qo'llash kerak
qo'shib qo'ydi muallif icirellik, manba
Agar siz newsequentialid dan foydalansangiz, idni olish uchun jb-ga borishingiz kerak (xuddi identifikatorga o'xshash), shunday emasmi? Bu erda qanday foyda bor?
qo'shib qo'ydi muallif w0051977, manba
Yana bir foydalanish usuli bor: ketma-ketlikdagi qulflashning qiyinligi bo'lgan OLTP ma'lumotlar bazalarini keng kiritish. Oracle DBA do'stimga ko'ra, bu juda kamdan kam emas, buning uchun katta miqyosda yoki kümelenmelere ham ehtiyoj qolmaydi. • Oxir-oqibat, ortiqcha va kamchiliklarni torting (va UUIDsning leksik/kamchiliklarini UUID-larga xos bo'lmagan ba'zi bir plakatlarga o'xshamaydi.) Va o'lchash .
qo'shib qo'ydi muallif mirabilos, manba
"Mos keladigan-hidoyatga o'xshash" qiymati (masalan, c #da) yaratish orqali parchalanishni "yordamlash" mumkin. UuidCreateSequential quyidagicha ketma-ket GUIDlar hosil qiladi: 19F287B4-8830-11D9-8BFC-000CF1ADC5B7 19F287B5-8830-11D9-8BFC-000CF1ADC5B7 19F287B6-8830-11D9-8BFC-000CF1ADC5B7 19F287B7-8830-11D9-8BFC-000CF1ADC5B7 19F287B8-8830-11D9-8BFC -000CF1ADC5B7 ga qarang pinvoke.net/default.aspx/rpcrt4.UuidCreateSequential
qo'shib qo'ydi muallif granadaCoder, manba

Yo'q, demasligim kerak, GUIDlarni asosiy kalitlar sifatida ishlatmang. Aslida, men hozirda bunday BK bilan shug'ullanyapman va ular ishlash muammolarining asosiy sabablaridan biri.

Qo'shimcha 12 bayt tezda qo'shiladi; esda tuting, aksariyat PK lar boshqa stollarda FKs bo'ladi, va bitta stolda faqat uchta FK-larni endi har bir satr uchun 48 bayt qo'shimcha bo'ladi. Bu stolga va indekslarga qo'shiladi. Bundan tashqari, diskda I/U qo'shiladi. Ushbu qo'shimcha 12 bayt o'qish va yozishni talab qiladi.

Agar siz ketma-ket yo'l-yo'riqlarni ishlatmasangiz va PKlar kümelenmişse (aslida nima sodir bo'lsa), SQL vaqti-vaqti bilan ma'lumotlarning to'liq sahifalarini o'ngdagi "nuqta" ga ko'proq siqish uchun ko'chirish kerak. Ko'p sonli qo'shimchalar, yangilanishlar va o'chirib yuborilgan juda jurnali ma'lumotlar bazasi uchun, tezkor tarzda ishlaydigan narsalar.

Sinxronlashtirish yoki boshqa narsalar uchun noyob identifikatorga kerak bo'lsa, ustunli ustun qo'shing. Faqat pK ni qilmang.

4
qo'shib qo'ydi

Ushbu GUIDlarning dastur darajasida moslamalarni aniqlash uchun ishlatilganligini tushunaman. Ma'lumotlar bazasi darajasida asosiy kalit sifatida saqlanganmi?

Mana shu erda to'xtash kerak, u erda va qayta o'ylab ko'ring.

Ma'lumotlar bazasi asosiy kalitingiz hech qachon biznes mazmuniga ega bo'lishi kerak. Bu ta'rif bilan ma'nosiz bo'lishi kerak.

Shunday ekan, sizning biznes kalitingiz sifatida GUID va oddiy birlamchi kalit (odatda uzoq int) ma'lumotlar bazasi birlamchi kalit sifatida qo'shing. Noyoblikni ta'minlash uchun siz GUIDga yagona indeksni qo'yishingiz mumkin.

Bu, albatta, ma'lumotlar bazasi nazariyasi haqida gapiradi, lekin bu yaxshi amaliyotdir. Men asosiy kalitlarga ish mazmuniga ega ma'lumotlar bazalari bilan ishladim (bir mijoz ba'zi ma'lumotlar bazasi resurslarini masalan, xodimlarning soni, mijozlar raqamlari va hokazolarni qo'llash orqali o'ylab topdi) va bu har doim muammoga olib keladi.

2
qo'shib qo'ydi
@icirellik asosiy kalit ma'lumotlar bazasi ichki foydalanish uchun mo'ljallangan, ota-ona va bola yozuvlar va shunga o'xshash. Ilova mantig'i tomonidan foydalanish uchun mo'ljallangan emas, sizning biznes raqamingiz mahsulot raqami yoki nomi kabi foydalanasiz.
qo'shib qo'ydi muallif jwenting, manba
Qanday qilib dastur katmanından bir tamsayı asosiy kaliti yordamida so'rov qilishdan har xil? Shu nuqtada, u dastur qatlamidagi narsalarni aniqlash uchun ham ishlatiladi. Ma'lumotlar bazasidagi narsalarni dastur qatlamidan aniqlashning bir yo'li kerak.
qo'shib qo'ydi muallif icirellik, manba

Alohida ma'lumotlar bazasini yaratib, avtoto'ldirishni boshlang'ich kalitlardan (PK) foydalaning.

Nima uchun GUID/UUID o'rniga auto-incrementing ishlatiladi?

  • GUID (UUID) ning asosiy to'qnashuvlarga to'sqinlik qilmagani, chunki ular noyob bo'lmaydilar va ularning ko'plab manbalardan yaratilgani uchun ularni noyob qilishning usuli yo'q.
  • GUIDlar birlashtirilishga yordam bermaydi, chunki ular juda ko'p vaqtni talab qiluvchi birlashma jarayonini sezilarli darajada oshiradi, chunki juda ko'p muddatli, to'liq bo'lmagan PK va FK ustunlari qayta ishlanadi. Esda tutingki, ko'pchilik PK lar uchun kamida ikkita jadval mavjud, ular kamida 2 ta kalit bilan bir xil o'lchamdagi: o'zlarining PK va FK-ning birinchi stolga qaytishi. Barchasini birlashtirishda hal qilish kerak.

Lekin qanday qilib shardlarni, klasterlarni va boshqalarni boshqarish kerak?

  • Har bir shard/klaster/ma'lumotlar bazasini identifikatsiyalovchi alohida sütunlardan tashkil topgan ko'p sütunlı pK'ları yarating, bu esa o'z avtomatik arttırma kalitlarini boshqaradi. Misol uchun ...

Kümelenmiş jadval uchun 3-ustunli PK bo'lishi mumkin ...

 DB | SH | KEY     |
----|----|---------|
 01 | 01 | 1234567 |

Lekin nima haqida ...?

  • Ma'lumotlar bazasiga bir nechta tashriflar - Ko'pgina ilovalar ma'lumotlar bazasiga kiritilgunga qadar yaratilgan yozuvni noyob tarzda identifikatsiyalashga hojat yo'q, chunki bu ish/suhbat/har qanday narsa faqat bir vaqtning o'zida ishlaydi. Agar dastur haqiqatdan ham bu qobiliyatga muhtoj bo'lsa, ma'lumotlar bazasiga yuborilmagan vaqtinchalik PK dasturidan foydalaning . Ma'lumotlar bazasiga kiritilganidan so'ng, o'z shaxsiy avtomatlashtirilgan pikselni qo'yib qo'ying.

2
qo'shib qo'ydi
@RibaldEddie - JB qanday yo'l tutish uchun mo'ljallangan bo'lsa ... albatta. Yo'q qilish oson. Sizning ssenariyingiz sodir bo'lganda, uni dasturiy ta'minotga o'rnatilishi uchun xato deb hisoblayman va so'ngra satrni o'chirib tashlayman. Juda ham keng tarqalgan bo'lsa-da, ular bir-biriga birlashtirilgan bo'lishi kerak, shuning uchun bir xil narsa uchun bir oz farqli ma'lumotlar bilan ikkita rekord. Agar bitta yozuvda bitta ustun bo'sh bo'lsa va ikkinchisida qiymat bo'lsa, tanlov aniq va avtomatlashtirilishi mumkin. Ko'pincha datetimestamp avtomatlashtirilgan birlashtirilishi uchun ishlatilishi mumkin. Ba'zi bir nusxalar insonni bitirishi va biznes qoidalariga asoslangan holda birlashtirilganligini tasdiqlashi kerak.
qo'shib qo'ydi muallif yaplik, manba
Men ushbu satrlar bo'yicha javob uchun ko'proq narsani qo'shib qo'ydim. Android SD ilovasiga osib qo'yilganligim tufayli original javob to'liq bo'lmagan. Menimcha, dasturni qayta yozish katta ahamiyatga ega.
qo'shib qo'ydi muallif yaplik, manba
Ya'ni, sizning fikringizcha, jadvalda avtomatik ravishda birlamchi kalitni saqlab qolish uchun bir xil qatorlar bo'lishi kerak.
qo'shib qo'ydi muallif Unknown Zombie, manba
Jadval sxemasi bo'yicha sizning fikringiz qanday? Bu yagona noyob ustun ma'lumotlar bazasi yaratilgan auto-incrementing asosiy kaliti. Ayniqsa, chet el kalitiga ega bo'lmagan, lekin birlamchi kalit bilan bog'liq jadvallar uchun chet el kalitlari bo'lgan jadvallar uchun?
qo'shib qo'ydi muallif Unknown Zombie, manba
Person p1 = new Person();
p1.ID=GUID.NewGUID();
PersonRepository.Insert(p1);

Bu GUIDdan foydalanishning eng muhim sababi.

O'zingizning kodingizni bilmasdan yoki sizning qat'iylik qatlamingiz bilan aloqa qilishda noyob identifikatorni yaratishingiz juda katta foyda.

Sizning serveringiz, shaxsiy kompyuteringizda, noutbukda, oflayn qurilmangizda yaratilgan Shaxsning obyekti yoki dunyodagi barcha serverlarda noyob bo'lganligiga amin bo'lishingiz mumkin, ammo tarqatilgan.

Uni rdb yoki no-sql ma'lumotlar bazasida saqlab qo'yishingiz mumkin, uni har qanday web-brauzerga yuborishingiz yoki zudlik bilan bekor qilishingiz mumkin.

Yo'q, hech qanday to'qnashuv bo'lmaydi.

Indeksni indekslar biroz sekinlashishi mumkin, chunki indeksni buzish kerak bo'lishi mumkin.

Ha, u intdan katta.

  • tartibga solish.
  • tugatmasdan oldin otish kerak edi

Ko'pgina odamlar avtoulovlar haqida qayg'urayotganini bilaman va bu DBAs bilan tortishuvlarga sabab bo'lgan mavzu

Lekin men, albatta, qanchalik ustun yo'llar borligini juda yaxshi bilaman. Har qanday dasturda standart ko'rsatgichidan foydalaning.

Avto-intsiyalar ko'plab kamchiliklarga ega

  • Siz No-Sql tarqatilgan jb dan foydalanasiz.

  • Xabar kuyruksiz tizimidan foydalanasiz. JB-larga oldin narsalar identifikatsiya qilish kerak

  • Siz saqlashdan oldin bir nechta elementlarni yaratmoqdasiz va tahrir qildingiz. JBga urishdan oldin, har bir id talab qilinadi.

  • Siz yo'q qilish va qatorlarni qayta tiklashni xohlaysiz. Sizning auto inc idlaringizni hisobga olmaysiz va ishingiz tugagani uchun ishonch hosil qiling!

  • Ushbu yil har bir foydalanuvchi uchun qancha buyurtma olganingizni istamaysiz

  • Siz anonimlashtirilgan ma'lumotlarni ishlab chiqarishdan ko'chirib, aloqalarni buzmaslikka harakat qilishni xohlaysiz. Lekin mavjud test ma'lumotlarini yo'q qilmaslik.

  • Siz yagona ijarachi mahsulotingizni juda ko'p sotilgan ma'lumotlar bazasiga aylantirmoqchisiz, lekin har bir kishi buyurtma 56 mavjud.

  • Siz davomli, lekin vaqtincha bo'lgan narsalarni yaratasiz. (tugallanmagan buyruqlar) yana, barcha intslaringizni endi mavjud bo'lmagan narsalar bilan ishlatmang.

Ro'yxat cheksizdir va ular hamisha odamlar uchun doimo yuz beradigan haqiqiy muammolar. bir oz kattaroq FK xanjarlari tufayli diskdan bo'shashishdan farqli o'laroq

Nihoyat, intsiyalar bilan bog'liq juda katta masala siz ulardan chiqadi ! OK teorida yo'q, yuklar bor. Amalda siz amal qilasiz, chunki odamlar ularni tasodifiy sonlar kabi hech qanday ma'noga ega emaslar. ular kabi narsalarni qiladilar

  • Oh, mijozlar biz yangi ekanimizni o'ylashlarini istamayman.

  • orqali boshlang
  • Import ma'lumoti yukini import qilishim kerak edi, shuning uchun urug '1m ga yetkazdim, shuning uchun import nima ekanligini bilamiz

  • biz ma'lumotlarning toifasiga muhtojmiz. har bir davr keyingi milliondan boshlanadi, shuning uchun biz birinchi raqamni sehrli raqam sifatida ishlatishimiz mumkin

  • Barcha ma'lumotlarni yangi identifikatorlar bilan o'chirib tashladim va qayta topshirdim. Hatto audit jurnallari ham mavjud.

  • Kompozit kaliti bo'lgan ushbu raqamdan foydalaning, bu boshqa narsaning identifikatori sifatida

2
qo'shib qo'ydi
"Chaqmoq" degan so'zlaringizga bog'liq. Xuddi shu stolda, auto inc int bilan to'qnashuv ehtimolligi nolga teng.
qo'shib qo'ydi muallif sgwill, manba
O'ylaymanki, u erda qaysiki yaxshiroq bo'lgan bir nechta ilovalar bo'ladi. Noyob narsa e'tiborga olish kerak emas. Sizning "qusurlaringiz" ning intsiyalarida katta miqdordagi g'oyalar tarqalib ketgan, siz esa, sizning yo'lovchilaringizning ko'plab inqirozlarini hisobga olmaysiz.
qo'shib qo'ydi muallif Andy, manba
-1 uchun "Har qanday ilovada sukut bo'yicha ko'rsatmalar qo'llanishi kerak." Ga bog'liq. Va boshqalar ko'rsatdiki, GUIDlar/UUIDlar mutlaqo noyob bo'lishi kafolatlanmagan.
qo'shib qo'ydi muallif Geocode.Farm Staff, manba
"Bu bog'liqdir" javoblar foydasiz, chunki int yaxshi bo'lgan bir nechta ilovalar bo'ladi. Ammo sizning arizangiz shunchaki ulardan biri emas. GUIDlar siz olishingiz mumkin bo'lgan eng noyob narsadir
qo'shib qo'ydi muallif Ewan, manba
uning avtotexnika inti rahbarlikdan ko'ra to'qnashishi ehtimoli ko'proq
qo'shib qo'ydi muallif Ewan, manba
Bu faqat to'g'ri emas. osongina int urib to'qnashuvni osongina joriy urug'dan yuqori qiymat kiritish yoki urug'ni pastroq qiymatga qaytarish orqali osonlik bilan olish mumkin
qo'shib qo'ydi muallif Ewan, manba
Bu savolga javob beradigan narsa yo'q, lekin men (yana pastga siljishlarni to'xtatish uchun), ehtimol, real-hayot ilovalari to'qnashuvlarga duch kelmasligiga qaramay, nazariy jihatdan mumkin. (Yoki ehtimol, 45+ exabyte ma'lumotlar bazalari fikrimcha, ko'proq tarqalgan ...). Men "eng muhim sabab" biroz kuchliroq deb o'ylayman, biroq bu men uchun eng foydali narsa.
qo'shib qo'ydi muallif Pascalerino, manba

Buning uchun afzalliklar va kamchiliklar mavjud:

Yaxshi:

  1. Sizning kalitlaringiz doim bir xil uzunlikda (juda katta ma'lumotlar bazalari juda katta tugmachalarga ega bo'lishi mumkin)

1
qo'shib qo'ydi

Ha, GUIDdan asosiy kalit sifatida foydalanishingiz mumkin. Pastki tomon indeks kattaligi va tez parchalanishidir.

Ma'lumotlar bazalarida (masalan, klaster) yagona xususiyatga muhtoj bo'lmasangiz, sizning afzalligingiz afzalroq.

0
qo'shib qo'ydi
GUID generatorlar bir xil GUIDni bir necha marta ishlab chiqarishi mumkin, unda nuqson bor. Ular xohlayaptimi yoki yo'qmi, asosan, soat shoxlari orasidagi intervalda. Masalan, soat asosidagi generator faqat har 100 metrni belgilashi mumkin, bu 2 ta GUIDni o'sha mashina ichida 100 metrga teng talab qiladi. Buning oldini olish yo'llari bor, lekin asosan GUID generatorlar ko'pincha IP manzil va/yoki MAC manzili va vaqt tamg'asi bilan ishlamaydi.
qo'shib qo'ydi muallif jwenting, manba

Mana bu masala bo'yicha o'zim qabul qilmoqchiman - yechim GUID va int qiymatlari o'rtasida yarimli uy bo'lib, ikkalasining eng yaxshisini oladi.

Bu sinf, bir Kombinatsiyalangan GUID .

Asosiy afzallik, serverda ishlab chiqarilgan avtoto'ldirish qadriyatlarini (aylanishni talab qiladigan) ishlatishdan ko'ra, mijozning Id qiymatlarini yaratishga imkon beradi va deyarli nolga ega bo'lgan qiymatlarni qaytarish mumkin.

Yaratilgan qiymatlar faqat GUID uchun 16 dan ortiq 8 baytdan foydalanadi va ma'lum bir ma'lumotlar bazasi tartibida tartibiga bog'liq emas (masalan, GUID uchun SQL Server ). Qiymatlar butun imzolanmagan uzoq masofadan foydalanish uchun kengaytirilishi mumkin, biroq bu faqatgina aniq raqamlar imzolagan har qanday ma'lumotlar bazasi yoki boshqa ma'lumotlar ombori bilan bog'liq muammolarga olib kelishi mumkin.

public static class LongIdGenerator
{
   //set the start date to an appropriate value for your implementation 
   //DO NOT change this once any application that uses this functionality is live, otherwise existing Id values will lose their implied date
    private static readonly DateTime PeriodStartDate = new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    private static readonly DateTime PeriodEndDate = PeriodStartDate.AddYears(100);
    private static readonly long PeriodStartTicks = PeriodStartDate.Ticks;
    private static readonly long PeriodEndTicks = PeriodEndDate.Ticks;
    private static readonly long TotalPeriodTicks = PeriodEndTicks - PeriodStartTicks;

   //ensures that generated Ids are always positve
    private const long SEQUENCE_PART_PERMUTATIONS = 0x7FFFFFFFFFFF; 

    private static readonly Random Random = new Random();

    private static readonly object Lock = new object();
    private static long _lastSequencePart;

    public static long GetNewId()
    {
        var sequencePart = GetSequenceValueForDateTime(DateTime.UtcNow);

       //extra check, just in case we manage to call GetNewId() twice before enough ticks have passed to increment the sequence 
        lock (Lock)
        {
            if (sequencePart <= _lastSequencePart)
                sequencePart = _lastSequencePart + 1;

            _lastSequencePart = sequencePart;
        }

       //shift so that the sequence part fills the most significant 6 bytes of the result value
        sequencePart = (sequencePart << 16);

       //randomize the lowest 2 bytes of the result, just in case two different client PCs call GetNewId() at exactly the same time
        var randomPart = Random.Next() & 0xFFFF;

        return sequencePart + randomPart;
    }

   //used if you want to generate an Id value for a historic time point (within the start and end dates)
   //there are no checks, compared to calls to GetNewId(), but the chances of colliding values are still almost zero
    public static long GetIdForDateTime(DateTime dt)
    {
        if (dt < PeriodStartDate || dt > PeriodStartDate)
            throw new ArgumentException($"value must be in the range {PeriodStartDate:dd MMM yyyy} - {PeriodEndDate:dd MMM yyyy}");

        var sequencePart = GetSequenceValueForDateTime(dt.ToUniversalTime());
        var randomPart = Random.Next() & 0xFFFF;
        return ( sequencePart << 16 ) + randomPart;
    }

   //Get a 6 byte sequence value from the specified date time - startDate => 0 --> endDate => 0x7FFFFFFFFFFF
   //For a 100 year time period, 1 unit of the sequence corresponds to about 0.022 ms
    private static long GetSequenceValueForDateTime(DateTime dt)
    {
        var ticksFromStart = dt.ToUniversalTime().Ticks - PeriodStartTicks;
        var proportionOfPeriod = (decimal)ticksFromStart/TotalPeriodTicks;
        var result = proportionOfPeriod * SEQUENCE_PART_PERMUTATIONS;
        return (long)result;
    }

    public static DateTime GetDateTimeForId(long value)
    {
       //strip off the random part - the two lowest bytes
        var timePart = value >> 16;
        var proportionOfTotalPeriod = (decimal) timePart/SEQUENCE_PART_PERMUTATIONS;
        var ticks = (long)(proportionOfTotalPeriod * TotalPeriodTicks);
        var result = PeriodStartDate.AddTicks(ticks);
        return result;
    }
}
0
qo'shib qo'ydi