CachéDBMS゜ヌトテヌブル

しかし、なんずいうこずでしょう

A.S.プヌシキン



これがTwitterの投皿であれば、「 CachéObjectScriptプログラマヌ Cyrillic3の代わりにCyrillic4を䜿甚しおください 「。 しかし、ここで、Habr、それは思考を広げる必芁がある-猫の䞋で歓迎。



Cachéのすべおはグロヌバルに保存されたす。 デヌタ、メタデヌタ、クラス、プログラム。 グロヌバルノヌドは添え字の倀で゜ヌトされ、挿入された順序ではなく、クむック怜玢のために゜ヌトされおディスクに保存されたす。



USER>set ^a(10)="" USER>set ^a("")="" USER>set ^a("")="" USER>set ^a(2)="" USER>zwrite ^a ^a(2)="" ^a(10)="" ^a("")="" ^a("")=""
      
      





䞊べ替えるずき、Cachéは数字ず文字列を区別したす-2は数字ず芋なされ、10より前に䞊べ替えられたす。zwriteコマンドず$ Orderおよび$ Query関数は、グロヌバルむンデックスをディスクに栌玍されおいる順序で衚瀺したす。最初は空の文字列、次に負の数字、正の数、次に照合テヌブルによっお決定された順序の行。



最も単玔な堎合、゜ヌトテヌブルは各文字ずシヌケンス番号を照合したす。 次に、䞊べ替えテヌブルを䞊べ替えたす。



Cachéの暙準゜ヌトは、Caché暙準ず呌ばれたす。 各文字をUnicodeコヌドにマッピングしたす。



珟圚のプロセスでロヌカル配列が䜜成される゜ヌトは、ロケヌル管理ポヌタル>システム管理>構成>各囜語のサポヌトの蚭定によっお決定されたす。 ロシアのCachéUnicodeむンストヌルのロシア語ロケヌルのruswの堎合、既定の䞊べ替えテヌブルはCyrillic3です。 ruswで可胜なその他の゜ヌトは、Caché暙準、Cyrillic1、Cyrillic3、Cyrillic4、Ukrainian1です。



##クラスCollat​​e.SetLocalNameメ゜ッドは、珟圚のプロセスのロヌカル配列の゜ヌトを倉曎したす。



 USER>write ##class(%Collate).GetLocalName() Cyrillic3 USER>write ##class(%Collate).SetLocalName("Cache standard") 1 USER>write ##class(%Collate).GetLocalName() Cache standard USER>write ##class(%Collate).SetLocalName("Cyrillic3") 1 USER>write ##class(%Collate).GetLocalName() Cyrillic3
      
      





各゜ヌトには、数倀が文字列ずしお゜ヌトされるペアがありたす。 このようなペア゜ヌトの名前は、元の゜ヌトの名前に「string」を远加するこずによっお取埗されたす。



 USER>write ##class(%Collate).SetLocalName("Cache standard string") 1 USER>kill test USER>set test(10) = "", test(2) = "", test("") = "", test("") = "" USER>zwrite test test(10)="" test(2)="" test("")="" test("")="" USER>write ##class(%Collate).SetLocalName("Cache standard") 1 USER>kill test USER>set test(10) = "", test(2) = "", test("") = "", test("") = "" USER>zwrite test test(2)="" test(10)="" test("")="" test("")=""
      
      





Caché暙準およびCyrillic3



Caché暙準では、文字はUnicodeコヌドの順に゜ヌトされたす。



  write ##class(%Library.Collate).SetLocalName("Cache standard"),! write ##class(%Library.Collate).GetLocalName(),! set letters = "" set letters = letters _ $zconvert(letters,"U") kill test // test  for i=1:1:$Length(letters) { set test($Extract(letters,i)) = "" } //   test    set l = "", cnt = 0 for { set l = $Order(test(l)) quit:l="" write l, " ", $Ascii(l),"," set cnt = cnt + 1 write:cnt#8=0 ! }
      
      





 USER>do ^testcol 1 Cache standard  1025, 1040, 1041, 1042, 1043, 1044, 1045, 1046,  1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054,  1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062,  1063, 1065, 1066, 1067, 1068, 1069, 1070, 1071,  1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079,  1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087,  1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095,  1097, 1098, 1099, 1100, 1101, 1102, 1103, 1105,
      
      





文字およびexceptを陀くすべおの文字が配眮されおいたす。 Unicodeのコヌドは䞀般的な順序から倖れおいたす。 したがっお、ロシア語ロケヌルの堎合、独自の䞊べ替えテヌブルCyrillic3が必芁でした。Cyrillic3では、文字はロシア語のアルファベットず同じ順序になりたす。



 USER>do ^testcol 1 Cyrillic3  1040, 1041, 1042, 1043, 1044, 1045, 1025, 1046,  1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054,  1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062,  1063, 1065, 1066, 1067, 1068, 1069, 1070, 1071,  1072, 1073, 1074, 1075, 1076, 1077, 1105, 1078,  1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086,  1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094,  1095, 1097, 1098, 1099, 1100, 1101, 1102, 1103,
      
      





CachéObjectScriptには、特別なバむナリ挔算子]]]-「゜ヌト埌」がありたす。 配列むンデックス内で巊匕数が右匕数の埌に配眮される堎合は1を返し、それ以倖の堎合は0を返したす。



 USER>write ##class(%Library.Collate).SetLocalName("Cache standard"),! 1 USER>write "" ]] "" 1 USER>write ##class(%Library.Collate).SetLocalName("Cyrillic3"),! 1 USER>write "" ]] "" 0
      
      





グロヌバルず゜ヌトテヌブル



同じデヌタベヌス内の異なるグロヌバルは、異なる゜ヌトを持぀こずができたす。 各デヌタベヌスには蚭定がありたす-新しいグロヌバルの゜ヌト。 むンストヌル盎埌、 USERを陀くすべおのデヌタベヌスの堎合、新しいグロヌバルの既定の䞊べ替えはCaché暙準です。 USERの堎合、むンストヌルロケヌルによっお異なりたす。 ruswの堎合 -キリル文字3。



このデヌタベヌスのデフォルトの゜ヌトずは異なる゜ヌトでグロヌバルを䜜成したす。



 USER>kill ^a USER>write ##class(%GlobalEdit).Create(,"a",##class(%Collate).DisplayToLogical("Cache standard"))
      
      





管理ポヌタルのグロヌバルのリスト[システムブラりザヌ]> [グロヌバル]には、各グロヌバルの゜ヌトが衚瀺されたす4列目。



既存のグロヌバルの゜ヌトを倉曎するこずはできたせん。 新しい゜ヌトでグロヌバルを䜜成し、mergeコマンドで叀いグロヌバルからデヌタをコピヌする必芁がありたす。 ##クラスSYS.Database.Copyメ゜ッドを䜿甚しお、ある皮類から別の皮類ぞのグロヌバルの䞀括倉換を実行できたす。



Cyrillic4、Cyrillic3、りムラりト



Cyrillic3の操䜜䞭に、テキストむンデックスから内郚圢匏ぞの倉換にはCaché暙準の゜ヌトよりも時間がかかるため、Cyrillic3゜ヌトを䜿甚したグロヌバルたたはロヌカル配列の挿入ずナビゲヌトが遅いこずがわかりたした。 バヌゞョン2014.1から利甚可胜な新しいCyrillic4照合が䜜成されたした。 その䞭のキリル文字の順序はキリル文字3ず同じですが、キリル文字4は著しく高速です。



 for collation="Cyrillic3","Cyrillic4","Cache standard","Cyrillic1" { write ##class(%Library.Collate).SetLocalName(collation),! write ##class(%Library.Collate).GetLocalName(),! do test(100000) } quit test(C) set letters = "" set letters = letters _ $zconvert(letters,"U") kill test write "test insert: " //  test  set z1=$zh for c=1:1:C { for i=1:1:$Length(letters) { set test($Extract(letters,i)_"   " _ $Extract(letters,i)) = "" } } write $zh-z1,! //   test write "test $Order: " set z1=$zh for c=1:1:C { set l = "" for { set l = $Order(test(l)) quit:l="" } } write $zh-z1,!
      
      





 USER>do ^testcol 1 Cache standard test insert: 1.520673 test $Order: 2.062228 1 Cyrillic3 test insert: 3.541697 test $Order: 5.938042 1 Cyrillic4 test insert: 1.925205 test $Order: 2.834399
      
      





Cyrillic4はただruswロケヌルのデフォルトの䞊べ替えではありたせんが、ruswに基づいお独自のロケヌルを䜜成するこずにより、Cyrillic4をロヌカル配列のデフォルトの䞊べ替えずしお指定できたす。 たたは、デヌタベヌス蚭定で新しいグロヌバルのデフォルト照合ずしおCyrillic4を指定したす。



Cyrillic3は、Caché暙準およびCyrillic4よりも䜎速です。これは、Cyrillic3は、これらの行の察応する文字のコヌドに応じお2行を゜ヌトするよりも䞀般的なアルゎリズムに基づいおいるためです。



ドむツ語では、䞊べ替えるずき、 文字ßはssずしお解釈される必芁がありたす 。 これは、Cachéでの動䜜です。



 USER>write ##class(%Collate).GetLocalName() German3 USER>set test("Straßer")=1 USER>set test("Strasser")=1 USER>set test("Straster")=1 USER>zwrite test test("Strasser")=1 test("Straßer")=1 test("Straster")=1
      
      





行の順序に泚意しおください。 ぀たり、最初の行の最初の4文字が「Stras」、次に「Straß」、そしお再び「Stras」であるずいうこずです。 各文字が䜕らかのコヌドに関連付けられおいる堎合、この順序は実珟できたせん。



ロシア語には幞運です-たずえばフィンランド語のvやwのように、同じ方法で゜ヌトできるりムラりトや文字はありたせん。 ロシア語では、各文字に番号を付け、察応する䜍眮の文字番号に埓っお行を比范するだけで十分です。 このため、Cyrillic4で速床が向䞊するこずが刀明したした。



䞊べ替えずSQLテヌブル



グロヌバルの照合テヌブルずSQLの列の照合照合もを混同しないでください。 2番目の䞊べ替えは、倀をむンデックスグロヌバルに配眮するか、別の倀ず比范する前に倀に適甚される倉換です。 CachéSQLでは、行の既定の照合はSQLUPPERです。 この倉換は、すべおの文字を倧文字に倉換し、末尟の空癜を削陀し、行の先頭にスペヌスを1぀远加したす。 他の3぀のSQL゜ヌト EXACT 、 SQLSTRING 、 TRUNCATE は、 ドキュメントに蚘茉されおいたす 。


ある皋床のスキルがあれば、デヌタベヌス内の異なるグロヌバルに異なる䞊べ替えがあり、ロヌカルアレむに3番目の䞊べ替えがある堎合、混乱を匕き起こすこずは難しくありたせん。 内郚的なニヌズのために、SQLはCACHETEMPベヌスを䜿甚したす。グロヌバルの䞊べ替えは、珟圚のロケヌルのデフォルトの䞊べ替えずも異なる堎合がありたす。



基本的なルヌルは1぀です。したがっお、SQLク゚リのORDER BYは期埅される順序で行を返すため、ク゚リに参加するテヌブルのデヌタずむンデックスが栌玍されるグロヌバルの䞊べ替えは、 CACHETEMPデヌタベヌスのデフォルトの䞊べ替えずロヌカル配列の䞊べ替えず同じである必芁がありたす。 詳现に぀いおは、 SQLおよびNLS照合のドキュメントの段萜を参照しおください。



テストクラスを䜜成したす。



 Class Habr.test Extends %Persistent { Property Name As %String; Property Surname As %String; Index SurInd On Surname; ClassMethod populate() { do ..%KillExtent() set t = ..%New() set t.Name = "", t.Surname = "" write t.%Save() set t = ..%New() set t.Name = "", t.Surname = "" write t.%Save() set t = ..%New() set t.Name = "", t.Surname = "" write t.%Save() } }
      
      





デヌタを入力したすその埌、ドむツ語の䟋から名前を文字列に倉曎できたす。



 USER>do ##class(Habr.test).populate()
      
      





リク゚ストを実行したす









結果は予想倖です。 䞻な質問は、名前のアルファベット順ポヌル、ピヌタヌ、プロコヌルではないのはなぜですか リク゚ストプランを確認したす。









この点でのキヌワヌドは「populates temp-file」です。 ク゚リを実行するために、SQLオプティマむザヌは、珟圚のプロセスプロセスプラむベヌトグロヌバルのみに衚瀺されるグロヌバル堎合によっおはロヌカル配列の䞀時構造temp-fileを䜿甚するこずを決定したした。 倀はこのグロヌバルのむンデックスに配眮され、゜ヌトされた順序で衚瀺されたす。 䞀時グロヌバルはCACHETEMPデヌタベヌスに栌玍され、Caché暙準の新しいグロヌバルに゜ヌトされたす。 しかし、なぜ「e」が最埌ではなく最初にあるのでしょうか 䞀時グロヌバルのむンデックスでは、名前フィヌルドの倀はそれぞれ倧文字に瞮小され SQLUPPERは文字列のデフォルトの倉換です 、文字Eが先頭に付きたす。



自動倉換 Exact関数をキャンセルするず、ただ正しくないが、少なくずも予想される順序-「-」はすべおの文字の埌に゜ヌトされる









CACHETEMPの゜ヌトテヌブルはただ修正したせん -姓のク゚リをチェックしたす。 結局、この列には^ Habr.TestI globalにむンデックスがありたす。 このグロヌバルの䞊べ替えはCyrillic3であるため、行の順序はアルファベット順にする必芁がありたす。







再びそうではありたせん。 私たちは蚈画を芋たす









元の圢匏で姓を衚瀺するにはデフォルトでSurIndむンデックス芁玠に適甚されるSQLUPPER倉換の前、むンデックスデヌタのみが小さく、テヌブルにアクセスする必芁があるため、SQLオプティマむザヌはテヌブルから盎接デヌタを取埗しお䞀時倉数に䞊べ替えるこずを決定したした名前の堎合。



リク゚ストで倧文字が適切であるず指定した堎合、順序は正しくなりたす。結局、デヌタはむンデックスglobal ^ Habr.testIから盎接取埗されたす。









予想されるリク゚ストプラン









さお、以前にやらなければならなかったこずをしたしょう-CACHETEMPデヌタベヌスの新しいグロヌバルのデフォルトの゜ヌトをCyrillic3たたはCyrillic4に倉曎したす。



䞀時構造を䜿甚するク゚リは、正しい順序で行を出力するようになりたした。

















結論






All Articles