আমি কি বারচার ব্যবহার করব (36) না এটি করার আরও ভাল কোনও উপায় আছে?
আমি কি বারচার ব্যবহার করব (36) না এটি করার আরও ভাল কোনও উপায় আছে?
উত্তর:
আমার ডিবিএ আমাকে জিজ্ঞাসা করেছিল যে আমি যখন আমার সামগ্রীর জন্য জিইউইডিগুলি সঞ্চয় করার সর্বোত্তম উপায় সম্পর্কে জিজ্ঞাসা করি তখন কেন আমি 16 বাইট সংরক্ষণ করতে হবে যখন আমি একটি পূর্ণসংখ্যার সাথে 4 বাইটে একই জিনিস করতে পারি। যেহেতু তিনি সেই চ্যালেঞ্জটি আমার কাছে রেখেছিলেন আমি ভেবেছিলাম এখনই এটির উল্লেখ করার জন্য ভাল সময়। বলা হচ্ছে যে...
আপনি যদি স্টোরেজ স্পেসের সর্বাধিক অনুকূল ব্যবহার করতে চান তবে আপনি CHAR (16) বাইনারি হিসাবে একটি গাইড স্টোর করতে পারেন।
আমি এটি একটি চর হিসাবে সংরক্ষণ করতে হবে (36)
-
।
থাবাডডউগের উত্তরে যুক্ত করে, 36 টি দৈর্ঘ্যের স্ট্রিং থেকে 16 এর বাইট অ্যারেতে ফিরে পেতে এই হ্যান্ডি ফাংশনগুলি (আমার এক জ্ঞানী কলেজের জন্য ধন্যবাদ) ব্যবহার করুন।
DELIMITER $$
CREATE FUNCTION `GuidToBinary`(
$Data VARCHAR(36)
) RETURNS binary(16)
DETERMINISTIC
NO SQL
BEGIN
DECLARE $Result BINARY(16) DEFAULT NULL;
IF $Data IS NOT NULL THEN
SET $Data = REPLACE($Data,'-','');
SET $Result =
CONCAT( UNHEX(SUBSTRING($Data,7,2)), UNHEX(SUBSTRING($Data,5,2)),
UNHEX(SUBSTRING($Data,3,2)), UNHEX(SUBSTRING($Data,1,2)),
UNHEX(SUBSTRING($Data,11,2)),UNHEX(SUBSTRING($Data,9,2)),
UNHEX(SUBSTRING($Data,15,2)),UNHEX(SUBSTRING($Data,13,2)),
UNHEX(SUBSTRING($Data,17,16)));
END IF;
RETURN $Result;
END
$$
CREATE FUNCTION `ToGuid`(
$Data BINARY(16)
) RETURNS char(36) CHARSET utf8
DETERMINISTIC
NO SQL
BEGIN
DECLARE $Result CHAR(36) DEFAULT NULL;
IF $Data IS NOT NULL THEN
SET $Result =
CONCAT(
HEX(SUBSTRING($Data,4,1)), HEX(SUBSTRING($Data,3,1)),
HEX(SUBSTRING($Data,2,1)), HEX(SUBSTRING($Data,1,1)), '-',
HEX(SUBSTRING($Data,6,1)), HEX(SUBSTRING($Data,5,1)), '-',
HEX(SUBSTRING($Data,8,1)), HEX(SUBSTRING($Data,7,1)), '-',
HEX(SUBSTRING($Data,9,2)), '-', HEX(SUBSTRING($Data,11,6)));
END IF;
RETURN $Result;
END
$$
CHAR(16)
আসলে একটি BINARY(16)
, আপনার পছন্দসই গন্ধ চয়ন করুন
কোডটি আরও ভালভাবে অনুসরণ করতে নীচে ডিজিটাল অর্ডার করা জিইউডি দিয়ে উদাহরণটি ধরুন। (অবৈধ চরিত্রগুলি উদাহরণস্বরূপ উদ্দেশ্যে ব্যবহৃত হয় - প্রতিটি জায়গাতেই একটি অনন্য চরিত্র রয়েছে)) ফাংশনগুলি বর্ধিত সূচক ক্লাস্টারিংয়ের জন্য কিছুটা অর্ডার অর্জনের জন্য বাইট ক্রমকে রূপান্তরিত করবে। পুনরায় সাজানো গাইডের উদাহরণ নীচে দেখানো হয়েছে।
12345678-9ABC-DEFG-HIJK-LMNOPQRSTUVW
78563412-BC9A-FGDE-HIJK-LMNOPQRSTUVW
ড্যাশগুলি সরানো হয়েছে:
123456789ABCDEFGHIJKLMNOPQRSTUVW
78563412BC9AFGDEHIJKLMNOPQRSTUVW
GuidToBinary
($ গাইড চর (36)) বাইনারি রিটার্ন করুন (16) কনটকেট রিটার্ন করুন (ইউএনএইচএক্স (সাবস্ক্রিং ($ গাইড, 7, 2))), ইউএনএইচএক্স (সাবস্ট্রাকশন ($ গাইড, ৫, ২)), ইউএনএইএক্সএক্স (সাবস্ক্রিং ($ গাইড, ৩, ২)), ইউএনএইচএক্স (সাবস্ক্রিং ($ গাইড, ১, ২)), ইউএনএইচএক্স (সাবস্ক্রিং ($ গাইড, ১২, ২)), ইউএনএইচএক্স (সাবস্ট্রাস্টিং ($ গাইড, 10, 2)), ইউএনএইএইচএক্স (সাবস্ক্রিং ($ গাইড, 17, 2)), ইউএনএইচএক্স (সাবস্ক্রিং ($ গাইড, 15, 2)), ইউএনএইচএক্স (সাবস্ক্রিং ($ গাইড, 20, 4)), ইউএনএইচএক্স (সাবস্ট্রাকশন ($ গাইড, 25, 12%));
CHAR
এবং BINARY
সমতুল্যতার উত্সের মাধ্যমে উন্নত করা যেতে পারে ( ডক্সগুলি মনে করে যে গুরুত্বপূর্ণ পার্থক্য রয়েছে এবং ক্লাস্টারড ইনডেক্সের পারফরম্যান্স কেন পুনরায় সাজানো বাইটগুলির সাথে আরও ভাল of
"আরও ভাল" নির্ভর করে আপনি যার জন্য অনুকূল করছেন।
আপনি সংরক্ষণের আকার / পারফরম্যান্স বনাম উন্নয়নের স্বচ্ছতা সম্পর্কে কতটা যত্নশীল? আরও গুরুত্বপূর্ণ - আপনি কি যথেষ্ট জিইউইডি তৈরি করছেন, বা এগুলি যথেষ্ট ঘন ঘন এনেছেন?
উত্তরটি যদি "না" char(36)
হয় তবে যথেষ্ট ভাল and অন্যথায়, binary(16)
যুক্তিসঙ্গত, তবে সাধারণ স্ট্রিং প্রতিনিধিত্ব থেকে পিছনে পিছনে রূপান্তর করতে আপনাকে মাইএসকিউএল এবং / অথবা আপনার পছন্দসই প্রোগ্রামিং ভাষার উপর ঝুঁকতে হবে।
বাইনারি (16) ভাল হবে, বার্চারের ব্যবহারের চেয়ে ভাল (32)।
কেসিডি পোস্ট করা গাইডডোবাইনারি রুটিনটি জিইউইডি স্ট্রিংয়ের টাইমস্ট্যাম্পের বিট লেআউটের জন্য অ্যাকাউন্টে চিহ্নিত করতে হবে। যদি স্ট্রিংটি ইউইউডি () মাইএসকিএল রুটিন দ্বারা ফিরিয়ে দেওয়া সংস্করণের মতো কোনও সংস্করণ 1 ইউইউডি উপস্থাপন করে তবে সময় উপাদানগুলি ডি বাদ দিয়ে 1-G অক্ষরে এম্বেড করা হয় the
12345678-9ABC-DEFG-HIJK-LMNOPQRSTUVW
12345678 = least significant 4 bytes of the timestamp in big endian order
9ABC = middle 2 timestamp bytes in big endian
D = 1 to signify a version 1 UUID
EFG = most significant 12 bits of the timestamp in big endian
আপনি যখন বাইনারিতে রূপান্তর করেন, তখন সূচকের সেরা আদেশটি হয়: EFG9ABC12345678D + বাকি।
আপনি 12345678 এ 78563412 এ অদলবদল করতে চান না কারণ বড় এন্ডিয়ান ইতিমধ্যে সেরা বাইনারি সূচক বাইট অর্ডার দেয়। তবে আপনি চাইছেন যে সর্বাধিক উল্লেখযোগ্য বাইটগুলি নিম্ন বাইটের সামনে চলে গেছে। সুতরাং, মাঝারি বিট এবং নিম্ন বিটগুলির পরে ইএফজি প্রথমে যায়। এক মিনিটের ব্যবধানে uuid () সহ এক ডজন বা তার বেশি ইউআইডি তৈরি করুন এবং আপনার এই অর্ডারটি কীভাবে সঠিক র্যাঙ্ক দেয় তা দেখতে হবে।
select uuid(), 0
union
select uuid(), sleep(.001)
union
select uuid(), sleep(.010)
union
select uuid(), sleep(.100)
union
select uuid(), sleep(1)
union
select uuid(), sleep(10)
union
select uuid(), 0;
/* output */
6eec5eb6-9755-11e4-b981-feb7b39d48d6
6eec5f10-9755-11e4-b981-feb7b39d48d6
6eec8ddc-9755-11e4-b981-feb7b39d48d6
6eee30d0-9755-11e4-b981-feb7b39d48d6
6efda038-9755-11e4-b981-feb7b39d48d6
6f9641bf-9755-11e4-b981-feb7b39d48d6
758c3e3e-9755-11e4-b981-feb7b39d48d6
প্রথম দুটি ইউইউডি সময়মতো নিকটে উত্পন্ন হয়েছিল। এগুলি কেবল প্রথম ব্লকের সর্বশেষ 3 নীবলিতে পরিবর্তিত হয়। এগুলি টাইমস্ট্যাম্পের সর্বনিম্ন উল্লেখযোগ্য বিট, যার অর্থ আমরা যখন এটিকে একটি সূচকযোগ্য বাইট অ্যারেতে রূপান্তর করি তখন আমরা সেগুলি ডানদিকে ঠেলে দিতে চাই। একটি পাল্টা উদাহরণ হিসাবে, সর্বশেষ আইডি সর্বাধিক বর্তমান, তবে কেসিডির অদলবদল অ্যালগরিদম এটি 3 য় আইডি (ডিসির আগে 3e, প্রথম ব্লকের সর্বশেষ বাইট) আগে রেখে দেবে।
সূচকের জন্য সঠিক ক্রমটি হ'ল:
1e497556eec5eb6...
1e497556eec5f10...
1e497556eec8ddc...
1e497556eee30d0...
1e497556efda038...
1e497556f9641bf...
1e49755758c3e3e...
সহায়তার তথ্যের জন্য এই নিবন্ধটি দেখুন: http://mysql.rjweb.org/doc.php/uuid
*** মনে রাখবেন যে আমি টাইমস্ট্যাম্পের উচ্চ 12 বিট থেকে নিবল সংস্করণ বিভক্ত করি না। এটি আপনার উদাহরণ থেকে ডি নিবলল। আমি শুধু এটি সামনে নিক্ষেপ। সুতরাং আমার বাইনারি ক্রম DEFG9ABC এবং তাই শেষ হচ্ছে। এটি সূচিত করে যে আমার সমস্ত সূচকযুক্ত ইউআইডিগুলি একই স্তম্ভের সাথে শুরু হয়। নিবন্ধটি একই কাজ করে।
যারা কেবল এটি পেরেছেন তাদের জন্য, পারকোনার গবেষণা অনুসারে এখন আরও অনেক ভাল বিকল্প রয়েছে।
এটি অনুকূল সূচকের জন্য ইউআইডি অংশগুলি পুনর্গঠন করে, তারপরে হ্রাস স্টোরেজের জন্য বাইনারি রূপান্তর করে।
এখানে সম্পূর্ণ নিবন্ধ পড়ুন
আমি @ বিঘ_29 দ্বারা উল্লিখিত ফাংশনগুলি আমার নির্দেশিকাগুলি নতুনগুলিতে রূপান্তরিত করার কারণে নীচের ফাংশনগুলি ব্যবহার করার পরামর্শ দেব (যে কারণে আমি বুঝতে পারি না)। এছাড়াও, আমি আমার টেবিলে যে পরীক্ষাগুলি দিয়েছি সেগুলিতে এইগুলি কিছুটা দ্রুত। https://gist.github.com/damienb/159151
DELIMITER |
CREATE FUNCTION uuid_from_bin(b BINARY(16))
RETURNS CHAR(36) DETERMINISTIC
BEGIN
DECLARE hex CHAR(32);
SET hex = HEX(b);
RETURN LOWER(CONCAT(LEFT(hex, 8), '-', MID(hex, 9,4), '-', MID(hex, 13,4), '-', MID(hex, 17,4), '-', RIGHT(hex, 12)));
END
|
CREATE FUNCTION uuid_to_bin(s CHAR(36))
RETURNS BINARY(16) DETERMINISTIC
RETURN UNHEX(CONCAT(LEFT(s, 8), MID(s, 10, 4), MID(s, 15, 4), MID(s, 20, 4), RIGHT(s, 12)))
|
DELIMITER ;
যদি আপনার মানক জিইউইডি হিসাবে গৃহীত চর / বার্চারের মান থাকে তবে আপনি কনক্যাট + সাবস্ক্রাইটির সমস্ত মন-বগল ক্রম ছাড়াই সহজ সরল CAST (মাইস্ট্রিং হিসাবে বিন্টার 16) ব্যবহার করে এটি বিনাইন (16) হিসাবে সংরক্ষণ করতে পারেন।
বিনের (১)) ক্ষেত্রগুলি স্ট্রিংয়ের চেয়ে অনেক দ্রুত গতি তুলনা / সাজানো / সূচী করা হয় এবং ডাটাবেসে দু'বার কম স্থানও নেয়
select CAST("hello world, this is as long as uiid" AS BINARY(16));
উত্পাদনhello world, thi