Выкарыстанне GUID ў якасці першаснага ключа

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/

Я разумею, што гэтыя ідэнтыфікатары GUID выкарыстоўваюцца для ідэнтыфікацыі аб'ектаў на ўзроўні прыкладанняў. Яны таксама захоўваюцца ў якасці першаснага ключа на ўзроўні базы дадзеных. Так, напрыклад, сказаць, што я меў наступны клас:

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

//Person Methods follow
}

Скажам, я хацеў стварыць новы чалавек у памяці, а затым устаўце Person ў базу дадзеных. Ці магу я проста зрабіць гэта:

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

Скажам, у мяне была база дадзеных, якая змяшчае мільёны і мільёны радкоў з GUID ў якасці першаснага ключа. Ці будзе гэта заўсёды быць унікальным? Ці магу я нават зразумець GUIDs правільна?

Я прачытаў гэтую артыкул раней: http://enterprisecraftsmanship.com/2014/11/15/CQS-з базай дадзеных згенераваных-IDS/. Гэта мяне бянтэжыць трохі, як уяўляецца, рэкамендаваць залатую сярэдзіну паміж GUIDs і цэлымі лікамі ў якасці першасных ключоў.

<�Моцны> Змяніць 11/06/18

Я прыйшоў да высновы, што Guids з'яўляецца больш прыдатным, чым Інтс для маіх патрабаванняў. Я выкарыстоўваю CQRS больш у гэтыя дні і ўпісвацца ў GUID, больш прыгожа.

Я заўважыў, што некаторыя распрацоўшчыкі мадэлююць GUIDs як радкі ў мадэлі прадметнай вобласці, напрыклад, тут: https://github.com/dotnet-architecture/eShopOnContainers/blob/dev/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs - у гэтым выпадку: IdentityGuid з'яўляецца GUID мадэлюецца як радок. Ці ёсць прычына, каб зрабіць гэта, акрамя таго, што тут гаворыцца: выкарыстоўваць карыстацкі аб'ект ці значэнне Guid ў якасці ідэнтыфікатара аб'екта ў размеркаванай сістэме? . Ці з'яўляецца гэта «нармальна» для мадэлявання GUID ў выглядзе радка ці я павінен мадэляваць яго як GUID ў мадэлі і базы дадзеных?

31
<�Я> Я прыйшоў да высновы, што Guids з'яўляецца больш прыдатным, чым Інтс для маіх патрабаванняў. Я кажу GUID з'яўляецца апошнім сродкам (і Інта па гэтым пытанні). Індэксацыя не мае сэнсу, і загадкавая, у лепшым выпадку, у запытах. Ад, складовыя ключы DSL-иш ў выкарыстанні, кантэкстная, апісальны, гнуткі і важнае значэнне для прадукцыйнасці. Запыты на падмностве складовага ПК могуць выкарыстоўваць яго. Сцеражыся супраць стварэння для яго першасных ключоў дзеля - там, дзе ніхто не апраўданы. Нічога дрэннага з індэксацыяй па меры неабходнасці на не-PK'ed табліц. PKs непарыўна звязваюцца структуры дадзеных, адносіны, і патрабаванні.
дададзена аўтар jbu, крыніца
Сістэма Я працую з у цяперашні час выкарыстоўвае UUID ,. Прыемная ўласцівасць з'яўляецца тое, што адназначна ідэнтыфікуе запіс, у адрозненне ад паслядоўнага ID, які ідэнтыфікуе запіс у гэтай табліцы.
дададзена аўтар Bakhtiyor, крыніца
@ W0051977 яны не робяць, але гэта можа дапамагчы - я бачыў (праўда, дрэнна закадаваныя) сістэмы, у якіх Ідэнтыфікатар ролі няправільна выкарыстоўваць у якасці UserRoleId - і распрацоўніка асяроддзяў нават працавалі, таму ID 1 працаваў у абодвух выпадках. З UUID, ідэнтыфікатары будуць адрознівацца.
дададзена аўтар Bakhtiyor, крыніца
Магчымы дублікат UUID супраць Integer
дададзена аўтар gnat, крыніца
Глядзі таксама: UUID сутыкненняў
дададзена аўтар gnat, крыніца
дададзена аўтар Euphoric, крыніца
Глядзіце таксама dba.stackexchange.com/questions/54690/… , а таксама мноства іншых пытанняў - гэтая тэма спытала, і адказаў, і спрачаліся пра тое, часта.
дададзена аўтар Arash, крыніца
Не гарантуецца быць унікальным, хоць гэта малаверагодна, што вы будзеце калі-небудзь бачыць сутыкненне. stackoverflow.com/questions/1155008/how-unique- гэта-UUID/& hellip;
дададзена аўтар icirellik, крыніца
@Justin, чаму запісы павінны быць унікальнай accross некалькі табліц?
дададзена аўтар w0051977, крыніца

10 адказы

GUID, па вызначэнні «глабальна унікальныя ідэнтыфікатары». Там вельмі падобныя, але трохі іншае паняцце ў Java называецца UUID, «Універсальна унікальныя ідэнтыфікатары». Імёны з'яўляюцца ўзаемазаменнымі для ўсіх практычнага выкарыстання.

GUID, гуляюць цэнтральную ролю ў тым, як Microsoft прадугледжана кластарызацыю баз дадзеных для працы, і, калі вам неабходна ўключыць дадзеныя з падлучаных крыніц часам, яны сапраўды дапамагаюць прадухіліць канфлікты дадзеных.

Некаторыя Pro-GUID Факты:

  • GUID, прадухілення сутыкненняў ключавых
  • GUID, дапамагчы з аб'яднаннем дадзеных паміж сеткамі, машын і інш.
  • SQL Server падтрымлівае полупоследовательным Guids, каб дапамагчы мінімізаваць індэкс фрагментацыі ( вых , некаторыя агаворкі)

Некаторы нязграбнасьць з GUIDs

  • Яны вялікія, 16 байт кожны
  • Яны выйшлі з ладу, так што вы не можаце сартаваць па ID і спадзяюцца атрымаць заказ ўстаўкі, як вы можаце на автоприращении ідэнтыфікатараў
  • Яны больш грувасткія для працы, асабліва на невялікіх наборах дадзеных (напрыклад, даведачныя табліцы)
  • Новая рэалізацыя GUID з'яўляецца больш надзейнай на SQL Server, чым у C# бібліятэкі (вы можаце мець паслядоўную Guids з SQL Server, у C# гэта выпадковае)

Ідэнтыфікатары GUID зробіць вашы індэксы больш, таму дыскавая прастора кошт індэксацыі слупок будзе вышэй. Выпадковыя ідэнтыфікатары GUID будзе фрагментаваць вашыя індэксы.

Калі вы ведаеце, што вы не збіраецеся сінхранізаваць дадзеныя з розных сетак, GUID, можа несці вялікую нагрузку, чым яны каштуюць.

Калі ў вас ёсць неабходнасць глынаць дадзеныя часам падлучаных кліентаў, яны могуць быць значна больш надзейнымі для прадухілення ключавых сутыкненняў, чым спадзявацца на ўсталяванне паслядоўнасці дыяпазонаў для гэтых кліентаў.

39
дададзена
Я зрабіў гэта супольнасць WIKI, і выдаліць самыя супярэчлівыя заявы. Ёсць у яго і зрабіць гэта найбольш правільны адказ. Я атрымліваю пачуццё, што я быў на правільным шляху, але не хапае яго на пару ключавых момантаў.
дададзена аўтар tim_yates, крыніца
Як зрабілі І. Дзякуй за зваротную сувязь, я даведаўся некалькі рэчаў.
дададзена аўтар tim_yates, крыніца
Там жа гэтая інфармацыя, якая можа дапамагчы таксама: blog.codinghorror.com/primary -Keys ідэнтыфікатары-супраць-ідэнтыфікатары GUID (Вы можаце мець паслядоўныя GUIDs ў SQL Server, якія з'яўляюцца паслядоўнымі для кожнай машыны ён уключаны)
дададзена аўтар tim_yates, крыніца
Вось некаторая інфармацыя: blogs.msdn.microsoft .com/sqlserverfaq/2010/05/27/& hellip; Я прызнаю, некаторыя з маёй інфармацыі аб GUIDs і кластарызацыі SQL Server старыя. Некаторыя рэчы мяняюцца, і некаторыя рэчы, якія застаюцца нязменнымі (напрыклад, SQL Server падтрымлівае толькі ад збояў кластарызацыю на працягу апошніх некалькіх гадоў)
дададзена аўтар tim_yates, крыніца
@JimmyJames, Бо тэг быў для SQL Server, я адмыслова ў адказ на гэтае пытанне. Oracle ніколі не быў пабудаваны вакол GUIDs або UUID, так што я не здзіўлены вашым вопытам.
дададзена аўтар tim_yates, крыніца
«Яны выйшлі з ладу, так што вы не можаце сартаваць па ID і спадзяюцца атрымаць заказ ўстаўкі, як вы можаце на автоинкрементном ід» Шчыра кажучы, я не вельмі зручна, абапіраючыся на якія з рэгулярнымі ідэнтыфікатарамі небудзь. Хоць гэта магчыма ў крайнім выпадку краю для ніжняга ідэнтыфікатару, каб атрымаць на дыск, пазней, я хацеў бы спадзявацца на карысныя сартавальных дадзеных, як ўстаўкі часовай пазнакі. Ідэнтыфікатары павінны разглядацца як адрасы памяці - усё ёсць адно, але само значэнне не мае сэнсу. Выкарыстоўвайце іх для tiebreakers самае. Тым больш, што калі ў вас ёсць насыпны груз, парадак ўстаўкі не гарантуецца.
дададзена аўтар Hao Sun, крыніца
@MaxVernon «не з'яўляецца аптымальным» масіўнае пераменшвання.
дададзена аўтар Andy, крыніца
«SQL Server аптымізаваныя для працы з GUIDs таму яно не павінна ўплываць на прадукцыйнасць запытаў шмат.» -1 Ня амаль аптымізавана дастаткова. Я працую з БД, дзе ўсё PKs з'яўляюцца ідэнтыфікатарамі GUID, і яго адна з асноўных прычын нізкай прадукцыйнасці.
дададзена аўтар Andy, крыніца
«SQL Server аптымізаваная для працы з GUIDs <�б> таму яно не павінна ўплываць на прадукцыйнасць запытаў шмат. » Гэта не так. Гэта зацвярджэнне мяркуе іншыя тыпы дадзеных не аптымізаваныя. Серверы баз дадзеных таксама маюць аптымізацыю для працы з простымі ИНТ значэннямі, напрыклад. Ідэнтыфікатары GUID/UUID, шмат павольней, чым пры выкарыстанні INT значэння 4 байта. 16 байт ніколі не будзе так хутка, як 4 байта - асабліва на машыне, якая апрацоўвае больш за 4 або 8 байт першапачаткова.
дададзена аўтар user192127, крыніца
@CortAmmon Згодна Wikipedia і RFC 4122 , яны з'яўляюцца сінонімамі. П. Ліч з Microsoft быў адзін са стваральнікаў RFC. Я думаю, так як RFC была створана, дзве такія ж. З RFC: "UUID, (Універсальна Unique Identifier), таксама вядомы як GUIDs (глабальны унікальны ідэнтыфікатар)." Я думаю, што гэта таксама карысна адзначыць, што ідэнтыфікатары GUID ня былі створаны MS. Яны проста стварылі новую назву тэхналогіі, прынятай ад іншых.
дададзена аўтар JimmyJames, крыніца
@MartinSmith Я лічу, што справа ў тым, што ўнутраны ідэнтыфікатар радкі ў БД з'яўляецца ідэнтыфікатар GUID. Гэта тое ж самае для Oracle, але я не ўпэўнены, што гэта той выпадак, калі DB абавязкова выкарыстоўвае яго ў кожным пошуку.
дададзена аўтар JimmyJames, крыніца
@MartinSmith Гэта па-за маёй кампетэнцыі, але ёсць сёе-тое на UUID вікіпедыя , што здаецца стаўленне.
дададзена аўтар JimmyJames, крыніца
@MartinSmith Гэта карысна інфармацыя, але я не аматар гэтага, як было адзначана ў розных каментарах тут.
дададзена аўтар JimmyJames, крыніца
Я разумею, што ідэнтыфікатары GUID з'яўляюцца сінонімамі UUID ,. UUID стандартнае імя. GUID з'яўляецца тое, што Microsoft прыдумаў іх да RFC 4122 .
дададзена аўтар JimmyJames, крыніца
Так, я проста мяркуючы, што гэта добрая ідэя, каб зразумець, сапраўды добра, што кампрамісы могуць быць звязаныя з гэтым. Вы згадалі некалькі, я не ведаю, калі гэта з'яўляецца усёабдымнай. У нашым выпадку мы выкарыстоўвалі «родныя» ідэнтыфікатары радкоў, як ПК. Такім чынам, хоць я згодны, што Oracle не справіцца з гэтым добра, ён на самай справе «пабудаваны» вакол гэтага. Гэта 128 біт так, па меншай меры, у 2017 годзе, вы прымушаеце DB выкарыстоўваць больш аднаго рэгістра за ключ.
дададзена аўтар JimmyJames, крыніца
+1, і я рэкамендую прачытаць дробны шрыфт, як БД апрацоўвае іх. Мы зрабілі гэта ў Oracle, і ён пайшоў вельмі дрэнна. Запыты павінны былі быць пераробленыя ў незразумелым чынам, каб патрапіць у індэкс. Іншая справа, што з'яўляецца праблематычным (IIRC) з'яўляецца тое, што GUID, створаныя на той жа машыне, прыкладна ў той жа час, як правіла, тое ж самае ў пачатку і ў канцы, але розныя ў сярэдзіне, так што вам трэба спецыяльную стратэгію індэксавання справіцца з гэтай сітуацыяй, асабліва ўлічваючы вельмі вялікі патэнцыял дыяпазону.
дададзена аўтар JimmyJames, крыніца
@MaxVernon з'яўляецца тое, што па прычыне, што некаторыя мяркуюць спалучэнне тэрыконаў + Guids?
дададзена аўтар Mark Maruska, крыніца
@ Ypercubeᵀᴹ - Я мяркую, што гэта адзін са спосабаў «абыйсці» праблему фрагментацыі табліцы. Нягледзячы на ​​тое, што б проста гандляваць адно пытанне за іншым. ня Кучы не падыходзяць, калі вы не можаце часта TRUNCATE TABLE іх.
дададзена аўтар Geocode.Farm Staff, крыніца
Калі г-жа Tripp кажа, што гэта праўда, гэта абсалютна <�я> з'яўляецца </я> дакладна.
дададзена аўтар Geocode.Farm Staff, крыніца
Я таксама зацікаўлены ў тым, што розніца ёсць паміж GUIDs і UUID ,. адказы, як гэтыя мяркуюць, павінны разглядацца сінонімамі, але Stack біржа з'яўляецца далёка ад асноўнага крыніцы <�я>/качкі
дададзена аўтар Cort Ammon, крыніца
GUID і UUID сталі synonymous.Trying ставіцца да іх па-іншаму проста будзе бянтэжыць людзей далей ўніз па дарозе.
дададзена аўтар icirellik, крыніца
<�Р> Ці будзе гэта заўсёды быць унікальным?

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

<�Р> Скажам, у мяне была база дадзеных, якая змяшчае мільёны і мільёны радкоў з GUID ў якасці першаснага ключа. </Р>

Мільёны і мільёны, вы, верагодна, бяспечныя. Мільён мільёнаў, і верагоднасць сутыкнення становіцца істотным. Там добрая навіна, хоць вы ўжо вычарпалі дыскавай прасторы да таго часу, што адбываецца.

<�Р> Ці магу я проста зрабіць гэта?

Ты можаш; гэта не зусім добрая ідэя. Ваша мадэль прадметнай вобласці звычайна не павінна быць генерацыі выпадковых лікаў; яны павінны быць ўваходы мадэлі.

Акрамя таго, калі вы маеце справу з ненадзейнай сеткай, дзе вы маглі б атрымаць дублікаты паведамленняў, а дэтэрмінавана генеруецца UUID будзе абараняць вас ад дублікатаў аб'ектаў. Але калі прысвоіць новае выпадковае лік для кожнага, то ёсць больш працы, каб ідэнтыфікаваць дублявання.

See the description of name-based uuid in RFC 4122

<�Р> Гэта «нармальна» для мадэлявання GUID ў выглядзе радка ці я павінен мадэляваць яго як GUID ў мадэлі і базы дадзеных?

Я не думаю, што гэта мае вельмі шмат. Для большасці з вашай даменнай мадэлі, гэта <�ет> ідэнтыфікатар ; адзіны запыт вы спытаеце яго, ці з'яўляецца ён ці не такі ж, як нейкай іншай ідэнтыфікатар. Ваша мадэль дамена не будзе нармальна глядзець на ў памяці прадстаўлення ідэнтыфікатара.

Калі GUID даступны як «прымітыўны тып» ў вашым дамене агностыку налады, я хацеў бы выкарыстаць яго; яна дазваляе падтрымліваць кантэкст, каб выбраць адпаведныя аптымізацыі, якія могуць быць даступныя.

Тое, што вы павінны прызнаць, аднак, заключаецца ў тым, што паданне ідэнтыфікатара, і ў памяці і ў памяці, гэта рашэнне, якое вы робіце ў вашай рэалізацыі, і таму вы павінны прымаць меры для забеспячэння таго, каб ступня друку коды ў спалучэнні з, што рашэнне мала - гл Парнас 1972 .

25
дададзена
Мільён мільёнаў = 2 ^ 40. Гэта складае 2 ^ 79 пар магчымых сутыкненняў. GUID мае 2 ^ 128 біт, таму шанец адзін у 2 ^ 49. Гэта значна больш верагодна, што ў вас ёсць памылка, якая паўторна выкарыстоўвае адзін і той жа GUID для двух запісаў, або што памылкова мяркуе, што існуе канфлікт там, дзе яго няма.
дададзена аўтар gnasher729, крыніца
Сапраўды, будучы ў стане паўторна вылічыць UUID/GUID, заснаваны на іншых дадзеных, гэта велізарная дапамогу, асабліва так, каб выяўляць дублікаты. Я калі-то пабудаваў сістэму апрацоўкі паведамленняў, якія захоўваюцца паведамленні і штурхнуў іх праз канвеер апрацоўкі. Я стварыў хэш паведамленні і выкарыстаў гэта ў якасці першаснага ключа ва ўсёй сістэме. толькі што, само па сабе, вырашыў мне шмат пытанняў, каб вызначыць паведамленне, калі мы павінны былі маштабавацца.
дададзена аўтар Newtopian, крыніца
Я адчуваю, што паняцце "<�я> дэтэрмінавана генеравацца UUID " мае важнае значэнне (гл Data Vault 2)
дададзена аўтар peterd, крыніца
Магчыма, гэтыя распрацоўшчыкі неабходна аптымізаваць свае кампрамісы па-рознаму.
дададзена аўтар VoiceOfUnreason, крыніца
Дзякуючы. Сапраўды гэтак жа я ясна; адказ паказвае на GUID ў мадэлі прадметнай вобласці (C #) і ўнікальны ідэнтыфікатар (а не кажуць VARCHAR) у базе дадзеных (SQL Server). Я заўважыў, што адрозніваецца ад таго, што знаходзіцца тут: github.com/dotnet-architecture/eShopOnContainers/blob/dev/sr‌ с/& hellip;
дададзена аўтар w0051977, крыніца
Я вяртаюся праз свае гістарычныя пытанні. Перад тым, як прыняць; маглі б вы зірнуць на мой рэдагаваць?
дададзена аўтар w0051977, крыніца
+1 за «вы ўжо вычарпалі дыскавай прасторы да таго часу, што адбываецца.»
дададзена аўтар w0051977, крыніца

GUID або UUID вельмі верагодна, будзе унікальны з-за таго, як яны ствараюцца, і яны забяспечваюць бяспечны спосаб гарантаваць унікальнасць без неабходнасці звязвацца з цэнтральнай уладай.

Перавагі GUIDs ў якасці першаснага ключа:

  • Вы можаце капіяваць дадзеныя паміж рознымі асколкамі кластара і не трэба турбавацца аб PK сутыкненнях.
  • Гэта дазваляе ведаць ваш першасны ключ, перш чым вы ўставілі якую-небудзь запіс.
  • Спрашчае логіку транзакцыі для ўстаўкі даччыных запісаў.
  • Не можа быць лёгка здагадацца.

У гэтым прыкладзе вы падалі:

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

Вызначэнне GUID да часу ўстаўкі можа захаваць падарожжа туды і назад у базу дадзеных пры ўстаўцы паслядоўных даччыных запісаў і дазваляеце ім здзяйсняць ў адной транзакцыі.

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

Падрывы ў GUIDs ў якасці першаснага ключа:

  • Яны вялікія 16 байт азначае, што яны будуць спажываць больш месца, як дадаюцца індэксы і знешнія ключы.
  • Яны не сартаваць так як яны ў асноўным выпадковыя ліку.
  • Выкарыстанне індэкса вельмі, вельмі, вельмі дрэнна.
  • Шмат лісця перамяшчэння.
  • Іх цяжка запомніць.
  • Іх цяжка выказаць словамі.
  • Яны могуць зрабіць URL, цяжэй чытаць.

Калі ваша прыкладанне не мае ніякай патрэбы ў шардинг або кластарызацыі было б лепш прытрымлівацца з больш простымі тыпамі дадзеных, такімі, як паміж або BIGINT.

Многія базы дадзеных маюць свае ўласныя ўнутраныя рэалізацыі, якія спрабуюць зьмякчыць праблемы захоўвання, выкліканыя GUID-х і SQL Server нават мае функцыю NEWSEQUENTIALID , каб дапамагчы з упарадкаваннем UUID-х дазваляе палепшыць выкарыстанне індэксаў і яны звычайна маюць лепшыя характарыстыкі.

Акрамя таго, з пункту гледжання тестеров, карыстальнік або распрацоўшчык, якія працуюць з дадаткам, выкарыстоўваючы ідэнтыфікатар GUID на працягу значна палепшыць сувязь. Уявіце сабе, што чытаць GUID па тэлефоне.

У рэшце рэшт, калі буйнамаштабная кластарызацыя або заблытвання URL-адрас не з'яўляецца абавязковым патрабаваннем, гэта больш практычна прытрымлівацца ідэнтыфікатараў автоинкрементных.

10
дададзена
@mirabilos Fon разладу, выкарыстоўваючы нейкі лакальнага патоку алгарытму Прывітанне-Ло будзе ІМХО больш простае рашэнне, і вы ўсё роўна атрымаеце менш і ў асноўным паслядоўныя ідэнтыфікатары.
дададзена аўтар David Nehme, крыніца
@mirabilos Акрамя таго, я б не рэкамендаваў выкарыстоўваць 128-бітныя ключы ў Oracle. Глядзіце мой каментар на адказ Берын ст. Прадукцыйнасць вакол гэтых відаў ПКС у Oracle можа быць жахлівым, калі не рабіць адмысловыя дапаможнікі для яго.
дададзена аўтар JimmyJames, крыніца
@mirabilos я быў бы зацікаўлены ў разуменні таго, як/калі гэта не вырашальныя шляхам павелічэння памеру блока паслядоўнасці.
дададзена аўтар JimmyJames, крыніца
Можа быць, я няправільна зразумеў. Я выказаў меркаванне, «Яны могуць зрабіць URL, цяжэй чытаць.» Маецца на ўвазе, што яны будуць выкарыстоўвацца там. Я не ўпэўнены, я згодны, што ў цэлым з дапамогай ключа ў URI абавязкова заўсёды праблема, але гэта можа быць, вядома.
дададзена аўтар JimmyJames, крыніца
@mirabilos Каб быць ясна, калі я кажу жудасна, мы скончылі тым, што ўстаўкі, якія прымалі <�б> хвілін ў радку. Гэта пачалося добра, але пасля таго, як былі 10 з тысяч радкоў, ён пайшоў у бок вельмі хутка. Калі гэта не відавочна, 10s тысяч радкоў вельмі маленькі столік.
дададзена аўтар JimmyJames, крыніца
Адзінае, што варта ўлічваць, што ў залежнасці ад тыпу UUID , яны ўтрымліваюць інфармацыю, якая патэнцыйна можа быць выкарыстоўваецца для ідэнтыфікацыі машыны яны генеруюцца на. Чыста выпадковы варыянт можа быць больш верагодна, сутыкнуцца без дастатковай энтрапіі. Гэта варта ўлічваць перад выкарыстаннем у URI.
дададзена аўтар JimmyJames, крыніца
Асноўная прычына, каб выкарыстоўваць іх у тым, што маючы GUID ў якасці кластэрнага ключа індэкса прывядзе да цяжкай фрагментацыі, дзе ў якасці паслядоўнага GUID не будзе. Гэта адбываецца з некаторымі перавагі ў прадукцыйнасці, а таксама некаторыя падводныя камяні бяспекі, напрыклад, быць прадказальнымі.
дададзена аўтар icirellik, крыніца
Згодны, хоць ніколі не варта падвяргаць іх першасны ключ у URL. Некаторы больш падыходны метад варта выкарыстоўваць, каб гарантаваць, што няма абароны дадзеных якія праходзяць на знешні system.s
дададзена аўтар icirellik, крыніца
Калі вы выкарыстоўваеце NEWSEQUENTIALID, то вы павінны пайсці да БД, каб атрымаць ідэнтыфікатар (напрыклад, з пасведчаннем міжнар), ці не так? У чым карысць тут.
дададзена аўтар w0051977, крыніца
Там яшчэ адзін выпадак выкарыстання: цяжкія базы дадзеных OLTP устаўка, у якой замыкалы для паслядоўнасці з'яўляецца вузкім месцам. Па словах майго сябра DBA Oracle, гэта не так рэдка, як гэта гучыць, вы нават не патрэбныя вялікі маштаб або кластары для гэтага. • У рэшце рэшт, абцяжарваюць плюсы і мінусы (і не блытайце плюсы/мінусы UUID, з плюсамі/мінусамі, якія не зьяўляюцца спэцыфічнымі для UUID, як гэта робяць некаторыя плакаты) і <�б> мера .
дададзена аўтар mirabilos, крыніца
Вы можаце «дапамагчы» фрагментацыя шляху стварэння "паслядоўнага кліенцкай боку-Guid-як» значэння (у C#, напрыклад). UuidCreateSequential генеруе паслядоўныя GUID, падобныя гэтым: 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 см pinvoke.net/default.aspx/rpcrt4.UuidCreateSequential
дададзена аўтар granadaCoder, крыніца

Я б сказаў, што няма, не выкарыстоўвайце GUIDs ў якасці першасных ключоў. Я на самой справе мае справу з такой БД у цяперашні час, і яны з'яўляюцца адным з асноўных прычын магутнасці сістэмы.

Дадатковыя 12 байт дадаць хутка; памятаеце, што большасць PKs будзе ФКС ў іншых табліцах, і толькі тры ФКС ў табліцы зараз у вас ёсць 48 байт дадатковых для кожнага радка. Гэта дадае ў табліцы і ў азначніках. Ён таксама дадае ў дыск I/O. Гэтыя дадатковыя 12 байт павінны быць прачытаныя і запісаныя.

І калі вы не выкарыстоўваеце паслядоўную GUIDs і PKs групуецца (што адбываецца па змаўчанні), SQL будзе час ад часу даводзіцца перамяшчаць цэлыя старонкі дадзеных вакол, каб сціснуць больш у правам «споце». Для высока транзакцыйнай базы дадзеных з вялікай колькасцю уставак, абнаўленняў і выдаленняў, усе ўгразнуць хутка.

Калі вам трэба нейкі ўнікальны ідэнтыфікатар для сінхранізацыі ці нешта, дадаць слупок Guid. Проста не робяць яго PK.

4
дададзена
<�Р> Я разумею, што гэтыя ідэнтыфікатары GUID выкарыстоўваюцца для ідэнтыфікацыі аб'ектаў на ўзроўні прыкладанняў. Яны таксама захоўваюцца ў якасці першаснага ключа на ўзроўні базы дадзеных.

Вось дзе вы павінны спыніцца, прама там, і пераасэнсаваць.

Ваш ключ першаснай базы дадзеных ніколі не павінен мець бізнес-сэнсу. Яно павінна быць бессэнсоўным па азначэнні.

Так дадаць GUID ў якасці бізнес-ключа, і нармальнага першаснага ключа (звычайна доўгае цэлае) у якасці ключа першаснай базы дадзеных. Вы заўсёды можаце паставіць унікальны індэкс на GUID, каб забяспечыць унікальнасць.

Гэта размова тэорыі баз дадзеных, вядома, але гэта добрая практыка, а таксама. Я меў справу з базамі дадзеных, дзе першасныя ключы мелі бізнес сэнс (адзін кліент думаў, каб захаваць некаторыя рэсурсы базы дадзеных, выкарыстоўваючы іх як ліку супрацоўнікаў, колькасці кліентаў і г.д. і да т.п., напрыклад), і гэта заўсёды прыводзіць да непрыемнасцяў.

2
дададзена
@icirellik першаснага ключа прызначаны для ўнутранага выкарыстання базы дадзеных, у сувязь бацькоў і даччыныя запісу і таму падобныя. Гэта не прызначана для выкарыстання логікі прыкладання, можна выкарыстоўваць бізнес-ідэнтыфікатары, якія, як і нумар прадукту або імя.
дададзена аўтар jwenting, крыніца
Як гэта па-іншаму, чым запыт ад прыкладнога ўзроўню з выкарыстаннем цэлага першаснага ключа? У гэты момант, ён таксама выкарыстоўваецца для ідэнтыфікацыі аб'ектаў на ўзроўні прыкладанняў. Вы, здаецца, патрэбен спосаб, каб ідэнтыфікаваць аб'екты ў базе дадзеных ад узроўню прыкладання.
дададзена аўтар icirellik, крыніца

<�Моцны> Заўсёды выкарыстаць згенераваныя базы дадзеных, автоинкрементные Першасныя ключы (PKs).

Навошта выкарыстоўваць автоинкрементные замест GUID/UUID?

  • GUID (UUID) s не перашкодзяць ключавых сутыкненняў, так як яны не з'яўляюцца унікальнымі, і няма ніякага спосабу, каб зрабіць іх унікальнымі, паколькі яны генеруюцца з шматлікіх крыніц.
  • GUID, не дапамагае з аб'яднаннем, паколькі яны значна павялічваюць ўжо працаёмкі працэс зліцця з вельмі доўгім, нецелых PK і FK калонамі, якія займаюць шмат часу, каб апрацаваць. Памятаеце, што для большасці першасных ключоў, будзе па меншай меры адзін іншая табліцай, па меншай меры, 2 ключа аднаго і той жа памеру: гэта ўласны PK і FK назад да першага стала. Усе павінны быць вырашаны ў зліцці.

Але як жа справіцца з аскепкамі, кластары і г.д.?

  • Стварэнне некалькіх слупкоў першасных ключоў, якія складаюцца з асобных слупкоў, якія ідэнтыфікуюць кожны асколак/кластар/базы даных/незалежна, што кіруе яго ўласнымі автоинкрементными ключы. Напрыклад ...

3-калонак PK для кластарнай табліцы можа быць ...

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

Але як наконт ...?

  • Некалькі паездак у базу дадзеных - Большасць прыкладанняў няма неабходнасці, каб адназначна ідэнтыфікаваць запіс ствараецца, пакуль яна не будзе ўстаўлена ў базу дадзеных, так што нітка/сесія/усе працуе толькі на адным адначасова. Калі дадатак сапраўды патрэбна гэтая магчымасць, выкарыстоўваць прыкладанне генеруецца часовы ПК , не перадаецца ў базу дадзеных . Хай база дадзеных затым пакласці яго ўласны автоинкрементируемый PK на радку, калі ён адсутнічае. Ўстаўкі будуць выкарыстоўваць часовы ПК, у той час як абнаўленне і выдаленне будуць выкарыстоўваць пастаянныя ПК, назначаныя ў базе дадзеных.

  • Прадукцыйнасць - кампутары могуць апрацоўваць простыя цэлыя лікі значна хутчэй, чым усе астатняе з-за значна вялікую вобласць, калі магчымыя значэнні для кожнага элемента ў GUID (37) у параўнанні з цэлым лікам (10). Памятаеце таксама, што кожны знак у GUID павінен спачатку быць ператвораны ў шэраг, каб маніпуляваць з дапамогай ЦПУ. </Р>

Common Misuses of Primary Keys PKs have only one purpose... to absolutely uniquely identify a row in a table. Anything else is an all-too-common misuse.

Выяўленне адсутных запісаў

  • Missing records cannot be detected by looking at the PKs. Bless QA for at least attempting to ensure data quality. However, they and programmer's lack of understanding of how keys in modern database systems are assigned often leads them to the misbelief that a missing number in an auto-incrementing PK means missing data. It does not because...
  • For performance, database systems allocate blocks of numbers in 'sequences'(batches, ranges) to minimize trips to the actual database in storage. The size of these sequences of numbers is often under the control of the DBA but may not be tunable on a per-table basis.
  • The key takeaway is... unused numbers from these sequences are never returned to the database so there are always gaps in the PK numbers.
  • Why would there be unused numbers you ask? Because a variety of database maintenance actions may cause sequences to be abandoned. These are things like restarts, bulk reloads of tables, some types of restoration from backups and some other operations.

сартаванне

  • сартаванне by PK is very error-prone since most people will think it lists the rows in the order they were created and that that corresponds to clock time. Mostly, but not necessarilly.
  • Database engines are optimized for maximum performance and that may mean delaying insert of the results of a long-running complicated transaction in order to insert short simple ones, "out-of-turn" so to speak.
2
дададзена
@RibaldEddie - Наколькі тое, што DB распрацаваны, каб дазволіць ... абсалютна. Пропускі лёгка. Калі адбываецца ваш сцэнар, я буду лічыць гэта памылка быць выпраўленая ў праграмным забеспячэнні, а затым выдаліць альбо радок. Значна больш агульны выпадак, хоць гэта два запісы для аднаго і таго ж з трохі рознымі дадзенымі таму яны павінны быць аб'яднаныя. Калі слупок пусты ў адной запісы і мае значэнне ў іншы, выбар відавочны і можа быць аўтаматызаваны. Часта datetimestamp можа быць выкарыстаны для арбітражу аўтаматызаванага аб'яднання. Некаторыя дублююць патрабуюць чалавека, каб скончыць і праверыць зліццё на аснове бізнес-правілаў.
дададзена аўтар yaplik, крыніца
Я дадаў значна больш да адказу ўздоўж гэтых ліній. Арыгінальны адказ быў няпоўным з прыкладання Android SE я на шыбеніцы. Я думаю, што галоўная перапісваюць прыкладанне знаходзіцца ў стадыі распрацоўкі.
дададзена аўтар yaplik, крыніца
Так, на ваш погляд, было б добра для табліцы, каб утрымліваць любую колькасць радкоў, якія былі ідэнтычныя, акрамя іх автоинкрементным першаснага ключа?
дададзена аўтар Unknown Zombie, крыніца
Што вы думаеце наконт схемы табліцы такім чынам, што толькі унікальны слупок ўяўляе сабой базу дадзеных, створаныя Автоинкрементный першасны ключ? У прыватнасці, для табліц, якія не маюць вонкавага ключа, але чый першасны ключ з'яўляецца знешніх ключом для некалькіх звязаных табліц?
дададзена аўтар Unknown Zombie, крыніца
Person p1 = new Person();
p1.ID=GUID.NewGUID();
PersonRepository.Insert(p1);

Гэта, безумоўна, самая важная прычына для выкарыстання GUIDs.

Той факт, што вы можаце стварыць унікальны ідэнтыфікатар без вашага кода ведаючы аб або зносінах з вашай настойлівасцю пластом з'яўляецца вялізным перавагай.

Вы можаце быць упэўненыя ў тым, што аб'ект Person проста генеруецца на сэрвэры, ПК тэлефон, ноўтбук, адсутнічае прылада ці нешта з'яўляецца унікальным для ўсіх сервераў ва ўсім свеце, аднак размеркаваны.

Вы можаце ўставіць яго ў любым выглядзе RDB базы дадзеных або не-SQL, файл, адправіць яго ў любы WebService або выкінуць яго адразу ж, як uneeded

Не, вы ніколі не атрымаеце сутыкнення.

Ды ўстаўкі могуць быць трохі больш павольна, так як індэкс можа спатрэбіцца круціў.

Так, гэта больш, чым міжнар.

  • рэдагаваць. прыйшлося адстрэліць да заканчэння ўверх.

Я ведаю, што многія людзі моцна аб аўто инкр Інтс і гэта спрэчнае з Абд

Але я сапраўды не магу дзяржава дастаткова моцна наколькі добрыя з'яўляюцца ідэнтыфікатары GUID. Вы павінны выкарыстоўваць GUIDs па <�моцны> па змаўчанні у любым дадатку.

аўто Inc Інтс мае шмат шмат недахопаў

  • Вы карыстаецеся No-Sql размеркаванай БД. Вы проста не можаце гаварыць са ўсімі іншымі асобнікамі, каб высветліць, што наступны нумар.

  • Вы можаце выкарыстоўваць сістэму чэргі паведамленняў. Рэчы трэба ідэнтыфікатары, перш чым яны патрапілі ў БД

  • Вы ствараеце некалькі элементаў і іх рэдагавання перад захаваннем. Кожны мае патрэбу ідэнтыфікатар, перш чым вы патрапілі ў БД

  • Вы жадаеце выдаліць і паўторна ўстаўкі радкоў. Пераканайцеся, што вы не падлічваць свае аўто, уключаючы дадатковыя ідэнтыфікатары і выбегчы!

  • Вы хочаце, каб не ставіць пад колькі заказаў вы прынялі ў гэтым годзе для кожнага карыстальніка

  • Вы жадаеце перамясціць дадзеныя з адасобленых вытворчасці, каб праверыць і захаваць адносіны некранутым. Але не выдаліць усе існуючыя тэставыя дадзеныя.

  • Вы хочаце аб'яднаць ваш адзіны арандатар прадукт у некалькіх здадзеных базе дадзеных, але кожны мае парадак 56.

  • Вы ствараеце аб'екты, якія захоўваюцца, але недаўгавечныя. (Незавершаныя заказы) зноў, не выкарыстоўваюць усе вашыя Інтс з матэрыялам, які больш не існуе.

Спіс можна працягваць бясконца, і яны ўсе рэальныя праблемы, якія адбываюцца з людзьмі ўвесь час. у адрозненні ад запуску з дыскавай прасторы з-за трохі больш перавалаў FK

Нарэшце, масавы выпуск з Інтс з'яўляецца <�моцны> вы бяжыце з іх !!! добра ў тэорыі, вы не робіце, гэта значыць нагрузкі. Але на практыцы вы робіце, таму што людзі не ставяцца да іх, як выпадковым лікаў, які не мае сэнсу. яны робяць такія рэчы, як

  • <�р> о, я не хачу кліентаў думаць, што мы новыя. пачынаюцца 10000 </р>
  • Я быў вымушаны імпартаваць нагрузку дадзеных, так што я проста павялічыў насеньне да 1м, таму мы ведаем, што імпартуецца

  • нам патрэбна катэгорыя-х дадзеных. кожны старт перыяду ў наступным мільён таму мы можам выкарыстоўваць першыя лічбы як магічнае лік

  • Я выдаліў і рэімпарт ўсіх дадзеных зноў з новымі ідэнтыфікатарамі. Ды нават часопісы аўдыту.

  • <�р> выкарыстоўваць гэты нумар, які з'яўляецца састаўным ключом, як ідэнтыфікатар гэтага другога рэчы
2
дададзена
Залежыць ад таго, што вы разумееце пад «Collide». У той жа табліцы, шанцы на аўто ІНК Int сутыкаюцца роўны нулю.
дададзена аўтар sgwill, крыніца
Я думаю, што будуць нейкія дзіўныя прыкладання, дзе GUID, якія лепш. Унікальная не самая важная рэч, каб разгледзець. Вашы «недахопы» з Інтс масава раздуць, і вы не лічыце любога з многіх мінусаў GUIDs.
дададзена аўтар Andy, крыніца
-1 для «Вы павінны выкарыстоўваць GUIDs па змаўчанні ў любым дадатку.» Гэта залежыць. І як іншыя паказалі, Guids/UUID , абсалютна не гарантавана быць унікальным.
дададзена аўтар Geocode.Farm Staff, крыніца
«Гэта залежыць ад» адказы бескарысныя, што там будуць некаторыя дзіўныя прыкладання, дзе ИНТ лепш. Але хутчэй за ўсё, ваша прыкладанне хіба адзін з іх. Ідэнтыфікатары GUID з'яўляюцца самай унікальнай рэччу, якую Вы можаце атрымаць
дададзена аўтар Ewan, крыніца
яго больш верагодна, што аўто вкл ИНТ сутыкнецца, чым GUID
дададзена аўтар Ewan, крыніца
вось толькі не так. вы можаце лёгка атрымаць ИНТ сутыкненне проста уставіўшы большае значэнне, чым бягучыя насенне ці скінуць насення да больш нізкага значэння
дададзена аўтар Ewan, крыніца
Там няма нічога дрэннага ў тым, фактычна гэты адказ, але я б (каб прадухіліць далейшыя downvotes), магчыма, зрабіць відавочнае перасцярога, што нават калі ў рэальным жыцці прыкладання не будуць сутыкацца з сутыкненняў, тэарэтычна гэта магчыма. (Або, магчыма, 45+ Exabyte базы дадзеных з'яўляюцца больш распаўсюджанымі, чым я думаў ...). Хоць я думаю, што мова «самая важная прычына» з'яўляецца трохі моцным, гэта тое, што я лічу найбольш карысным.
дададзена аўтар Pascalerino, крыніца

Як і ўсе, ёсць свае перавагі і недахопы рабіць гэта:

<�Моцны> Добра:

  1. Вашы ключы заўсёды такой жа даўжыні (вельмі вялікія базы дадзеных могуць мець вельмі вялікія клавішы)

  2. Унікальнасць у значнай ступені гарантаваная - нават тады, калі вы іх генерацыю з асобнай сістэмы, і/або не чыталі апошні ID з базы дадзеных

<�Моцны> Дрэнна:

  1. Як ужо згадвалася шмат вышэй. - вялікіх індэксаў і захоўвання дадзеных

  2. Вы не можаце замовіць па ID, вы павінны замовіць нешта яшчэ. Іншыя паказчыкі, верагодна, менш эфектыўны.

  3. Яны менш чытаным чалавекам. Цэлыя, як правіла, лягчэй аналізаваць, запамінаць і ўводзіць людзей. Выкарыстанне GUIDs ў якасці ідэнтыфікатараў у ИНЕКЕ на некалькі аб'яднаных табліцы могуць зрабіць вашу галаву плавіцца.

Як і ўсе, выкарыстоўваць іх там, дзе гэта неабходна, не дагматычных - у многіх сітуацыях автоинкрементные цэлыя лепш, часам Ідэнтыфікатары GUID вялікія.

1
дададзена

Так, вы можаце выкарыстоўваць GUID ў якасці першаснага ключа. Адваротны бок з'яўляецца памерам і хуткай фрагментацыя азначніка.

Калі вам не патрабуецца унікальнасць ўсёй базы дадзеных (напрыклад, кластар), з'яўляецца пераважнай лікам.

0
дададзена
GUID генератары могуць вырабляць адзін і той жа ідэнтыфікатар GUID больш за адзін раз, у гэтым складаецца недахоп. Ці будуць яны ці не, залежыць ад іх зярністасці, галоўным чынам, на інтэрвале паміж цікамі гадзін. напрыклад генератар тактавых імпульсаў на аснове можа толькі цікаць праз кожны 100 мс, што прыводзіць да 2 GUIDs запытанага у гэтым 100мсе на гэтай машыне можа быць аднолькавымі. Ёсць спосабы, каб пазбегнуць гэтага, у асноўным, але многія генератары GUID працуюць цалкам пакінуць IP-адрасы і/або MAC-адрас і змяняць час.
дададзена аўтар jwenting, крыніца

Вось маё ўзяцце па гэтым пытанні - рашэнне з'яўляецца паўдарогі паміж GUID і Int каштоўнасцяў, узяўшы лепшае з абодвух.

Клас генеруе псеўдавыпадковых (але павелічэнне з цягам часу) значэнне Id, які падобны на Грэбень GUID .

Ключавая перавага з'яўляецца тое, што яна дазваляе значэнне ідэнтыфікатара генеруецца на баку кліента, а не з выкарыстаннем значэнняў автоинкрементируемых згенераваныя на серверы (які патрабуе паездкі туды і назад) з амаль нулявым рызыкай дубляваных значэнняў.

Сфармаваныя значэння выкарыстоўваюць толькі 8 байт, а не 16 на GUID, а не залежаць ад аднаго канкрэтнага парадку сартавання базы дадзеных (напрыклад, Sql Server для GUIDs ). Значэння могуць быць пашыраныя, каб выкарыстоўваць увесь непадпісаны доўгі дыяпазон, але гэта выкліча б праблемы з якімі-небудзь базамі дадзеных або іншым сховішчам дадзеных, якія толькі што падпісалі цэлалікавых тыпамі.

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
дададзена