හෙලෝ, මම DBMS සඳහා යෙදුම් නිර්මාණය කරමි
බලය දැනෙන්න! (…හෝ කාර්ය සාධනය භුක්ති විඳින්න)
ඉහත සියල්ලම ටැරන්ටූල් දත්ත සමුදායන් සමඟ වැඩ කරන ඉහළ බර යෙදුම් නිර්මාණය කිරීම සඳහා ආකර්ෂණීය වේදිකාවක් බවට පත් කරයි. එවැනි යෙදුම් වලදී, බොහෝ විට දත්ත අනුකරණය සඳහා අවශ්ය වේ.
ඉහත සඳහන් කළ පරිදි, ටැරන්ටූල් තුළ දත්ත අනුකරණයක් ඇත. එහි ක්රියාකාරිත්වයේ මූලධර්මය වන්නේ ප්රධාන ලොගයේ (WAL) අඩංගු සියලුම ගනුදෙනු අනුපිටපත් මත අනුක්රමිකව ක්රියාත්මක කිරීමයි. සාමාන්යයෙන් එවැනි අනුකරණයක් (අපි එය තවදුරටත් අමතන්නෙමු පහත් මට්ටමේ) යෙදුම් දෝෂ ඉවසීම සහතික කිරීමට සහ/හෝ පොකුරු නෝඩ් අතර කියවීමේ භාරය බෙදා හැරීමට භාවිතා කරයි.
සහල්. 1. පොකුරක් තුළ අනුකරණය
විකල්ප අවස්ථාවක් සඳහා උදාහරණයක් වනුයේ එක් දත්ත ගබඩාවක සාදන ලද දත්ත සැකසීම/අධීක්ෂණය සඳහා තවත් දත්ත සමුදායකට මාරු කිරීමයි. අවසාන අවස්ථාවේ දී, වඩාත් පහසු විසඳුමක් භාවිතා කළ හැකිය ඉහළ මට්ටමේ අනුකරණය - යෙදුම් ව්යාපාර තාර්කික මට්ටමින් දත්ත අනුකරණය. එම. අපි DBMS තුළ ගොඩනගා ඇති සූදානම් කළ විසඳුමක් භාවිතා නොකරමු, නමුත් අප විසින් සංවර්ධනය කරන යෙදුම තුළ අපගේම අනුවර්තනය ක්රියාත්මක කරන්න. මෙම ප්රවේශය වාසි සහ අවාසි යන දෙකම ඇත. අපි වාසි ලැයිස්තුගත කරමු.
1. රථවාහන ඉතිරිකිරීම්:
- ඔබට සියලු දත්ත මාරු කළ නොහැක, නමුත් එයින් කොටසක් පමණක් (උදාහරණයක් ලෙස, ඔබට මාරු කළ හැක්කේ සමහර වගු, ඒවායේ තීරු හෝ යම් නිර්ණායකයක් සපුරාලන වාර්තා පමණි);
- අසමමුහුර්ත (වර්තමාන ටැරන්ටූල් - 1.10 අනුවාදයේ ක්රියාත්මක) හෝ සමමුහුර්ත (ටැරන්ටූල් හි පසුව අනුවාදවල ක්රියාත්මක කිරීමට) ප්රකාරයේදී අඛණ්ඩව සිදු කෙරෙන පහත මට්ටමේ ප්රතිනිර්මාණය මෙන් නොව, සැසිවලදී (එනම්, ද යෙදුම පළමුව දත්ත සමමුහුර්ත කරයි - හුවමාරු සැසි දත්ත, පසුව අනුකරණයේ විරාමයක් ඇත, ඉන්පසු ඊළඟ හුවමාරු සැසිය සිදු වේ, ආදිය);
- වාර්තාවක් කිහිප වතාවක් වෙනස් වී ඇත්නම්, ඔබට එහි නවතම අනුවාදය පමණක් මාරු කළ හැකිය (පහළ මට්ටමේ අනුකරණය මෙන් නොව, ප්රධාන මත සිදු කරන ලද සියලුම වෙනස්කම් අනුපිළිවෙලින් අනුපිළිවෙලින් නැවත වාදනය කරනු ලැබේ).
2. දුරස්ථ දත්ත සමුදායන් සමමුහුර්ත කිරීමට ඔබට ඉඩ සලසන HTTP හුවමාරුව ක්රියාත්මක කිරීමේදී දුෂ්කරතා නොමැත.
සහල්. 2. HTTP හරහා අනුකරණය
3. දත්ත මාරු කරන දත්ත සමුදා ව්යුහයන් සමාන විය යුතු නැත (එපමනක් නොව, සාමාන්ය අවස්ථාවෙහිදී, විවිධ DBMS, ක්රමලේඛන භාෂා, වේදිකා ආදිය භාවිතා කිරීමට පවා හැකිය).
සහල්. 3. විෂමජාතීය පද්ධතිවල අනුකරණය
අවාසිය නම්, සාමාන්යයෙන්, ක්රමලේඛනය වින්යාසයට වඩා දුෂ්කර/මිල අධික වන අතර, ගොඩනඟන ලද ක්රියාකාරිත්වය අභිරුචිකරණය කිරීම වෙනුවට, ඔබට ඔබේම ක්රියාත්මක කිරීමට සිදුවනු ඇත.
ඔබගේ තත්වය තුළ ඉහත වාසි තීරණාත්මක (හෝ අත්යවශ්ය කොන්දේසියක්) නම්, ඉහළ මට්ටමේ අනුකරණයක් භාවිතා කිරීම අර්ථවත් කරයි. Tarantool DBMS හි ඉහළ මට්ටමේ දත්ත අනුවර්තනය ක්රියාත්මක කිරීමට ක්රම කිහිපයක් බලමු.
වාහන තදබදය අවම කිරීම
එබැවින්, ඉහළ මට්ටමේ අනුකරණයේ එක් වාසියක් වන්නේ රථවාහන ඉතිරිකිරීමයි. මෙම වාසිය සම්පූර්ණයෙන් සාක්ෂාත් කර ගැනීම සඳහා, එක් එක් හුවමාරු සැසිය තුළ මාරු කරන ලද දත්ත ප්රමාණය අවම කිරීම අවශ්ය වේ. ඇත්ත වශයෙන්ම, සැසිය අවසානයේදී, දත්ත ග්රාහකය ප්රභවය සමඟ සමමුහුර්ත කළ යුතු බව අප අමතක නොකළ යුතුය (අවම වශයෙන් අනුකරණයට සම්බන්ධ දත්තවල එම කොටස සඳහා).
ඉහළ මට්ටමේ ප්රතිනිර්මාණය කිරීමේදී දත්ත මාරු කරන ප්රමාණය අවම කරන්නේ කෙසේද? සරල විසඳුමක් වනුයේ දිනය සහ වේලාව අනුව දත්ත තෝරා ගැනීමයි. මෙය සිදු කිරීම සඳහා, ඔබට දැනටමත් වගුවේ පවතින දින-කාල ක්ෂේත්රය භාවිතා කළ හැකිය (එය පවතී නම්). උදාහරණයක් ලෙස, "ඇණවුම්" ලේඛනයක "අවශ්ය ඇණවුම ක්රියාත්මක කිරීමේ කාලය" ක්ෂේත්රයක් තිබිය හැක - delivery_time
. මෙම විසඳුමේ ඇති ගැටළුව නම්, මෙම ක්ෂේත්රයේ අගයන් ඇණවුම් සෑදීමට අනුරූප වන අනුපිළිවෙලෙහි තිබිය යුතු නොවේ. එබැවින් අපට උපරිම ක්ෂේත්ර අගය මතක තබා ගත නොහැක delivery_time
, පෙර විනිමය සැසියේදී සම්ප්රේෂණය කරන ලද අතර ඊළඟ හුවමාරු සැසිය තුළ ඉහළ ක්ෂේත්ර අගයක් සහිත සියලුම වාර්තා තෝරන්න delivery_time
. හුවමාරු සැසි අතර අඩු ක්ෂේත්ර අගයක් සහිත වාර්තා එකතු කර තිබිය හැක delivery_time
. එසේම, ඇණවුම වෙනස්කම් වලට භාජනය විය හැකි අතර, එය කෙසේ වෙතත් ක්ෂේත්රයට බල නොපායි delivery_time
. අවස්ථා දෙකේදීම, වෙනස්කම් මූලාශ්රයෙන් ගමනාන්තයට මාරු නොකෙරේ. මෙම ගැටළු විසඳීම සඳහා, අපි "අතිච්ඡාදනය" දත්ත මාරු කිරීමට අවශ්ය වනු ඇත. එම. සෑම හුවමාරු සැසියකදීම අපි සියලුම දත්ත ක්ෂේත්ර අගය සමඟ මාරු කරන්නෙමු delivery_time
, අතීතයේ යම් කරුණක් ඉක්මවීම (උදාහරණයක් ලෙස, වත්මන් මොහොතේ සිට N පැය). කෙසේ වෙතත්, විශාල පද්ධති සඳහා මෙම ප්රවේශය අතිශයින් අතිරික්ත වන අතර අප උත්සාහ කරන රථවාහන ඉතුරුම් කිසිවක් නැති කර ගත හැකි බව පැහැදිලිය. ඊට අමතරව, මාරු කරන වගුවේ දින-වේලාවක් හා සම්බන්ධ ක්ෂේත්රයක් නොතිබිය හැකිය.
තවත් විසඳුමක්, ක්රියාත්මක කිරීම අනුව වඩාත් සංකීර්ණ, දත්ත ලැබීම පිළිගැනීමයි. මෙම අවස්ථාවෙහිදී, එක් එක් හුවමාරු සැසිය තුළදී, සියලු දත්ත සම්ප්රේෂණය කරනු ලැබේ, ලබන්නා විසින් ලදුපත තහවුරු කර නොමැත. මෙය ක්රියාත්මක කිරීම සඳහා, ඔබට මූලාශ්ර වගුවට බූලියන් තීරුවක් එක් කිරීමට අවශ්ය වනු ඇත (උදාහරණයක් ලෙස, is_transferred
) ග්රාහකයා වාර්තාව ලැබුණු බව පිළිගන්නේ නම්, අදාළ ක්ෂේත්රය අගය ගනී true
, ඉන් පසුව ප්රවේශය තවදුරටත් හුවමාරු වලට සම්බන්ධ නොවේ. මෙම ක්රියාත්මක කිරීමේ විකල්පයට පහත අවාසි ඇත. පළමුව, මාරු කරන ලද සෑම වාර්තාවක් සඳහාම, පිළිගැනීමක් ජනනය කර යැවිය යුතුය. දළ වශයෙන් කිවහොත්, මෙය මාරු කළ දත්ත ප්රමාණය දෙගුණ කිරීම හා වට සංචාර සංඛ්යාව දෙගුණ කිරීම හා සැසඳිය හැකිය. දෙවනුව, එකම වාර්තාව ග්රාහක කිහිපයකට යැවීමේ හැකියාවක් නොමැත (ලබන පළමු ග්රාහකයා තමාට සහ අනෙක් සියල්ලන්ටම රිසිට්පත තහවුරු කරයි).
ඉහත දක්වා ඇති අවාසි නොමැති ක්රමයක් නම් මාරු කළ වගුවට එහි පේළිවල වෙනස්කම් නිරීක්ෂණය කිරීමට තීරුවක් එක් කිරීමයි. එවැනි තීරුවක් දින-කාල වර්ගය විය හැකි අතර, වාර්තා එකතු කරන/වෙනස් කරන සෑම අවස්ථාවකම (පරමාණුක වශයෙන් එකතු කිරීම/වෙනස් කිරීම සමඟ) වත්මන් වේලාවට යෙදුම මඟින් සැකසිය/යාවත්කාලීන කළ යුතුය. උදාහරණයක් ලෙස, අපි තීරුව කියමු update_time
. මාරු කළ වාර්තා සඳහා මෙම තීරුවේ උපරිම ක්ෂේත්ර අගය සුරැකීමෙන්, අපට මෙම අගය සමඟ ඊළඟ හුවමාරු සැසිය ආරම්භ කළ හැකිය (ක්ෂේත්ර අගය සහිත වාර්තා තෝරන්න update_time
, කලින් ගබඩා කළ අගය ඉක්මවීම). අවසාන ප්රවේශයේ ගැටලුව වන්නේ දත්ත වෙනස්වීම් කණ්ඩායම් වශයෙන් සිදු විය හැකි බවයි. තීරුවේ ඇති ක්ෂේත්ර අගයන්හි ප්රතිඵලයක් ලෙස update_time
අද්විතීය නොවිය හැක. මේ අනුව, මෙම තීරුව කොටස් වශයෙන් (පිටුවෙන් පිටුවට) දත්ත ප්රතිදානය සඳහා භාවිතා කළ නොහැක. පිටුවෙන් පිටුව දත්ත සංදර්ශන කිරීමට, ඔබට බොහෝ විට ඉතා අඩු කාර්යක්ෂමතාවයක් ඇති අමතර යාන්ත්රණ නිර්මාණය කිරීමට සිදුවනු ඇත (උදාහරණයක් ලෙස, දත්ත සමුදායෙන් අගය සහිත සියලුම වාර්තා ලබා ගැනීම update_time
දී ඇති එකකට වඩා ඉහළ සහ නියැදියේ ආරම්භයේ සිට නිශ්චිත ඕෆ්සෙට් එකකින් ආරම්භ වන නිශ්චිත වාර්තා සංඛ්යාවක් නිෂ්පාදනය කිරීම).
පෙර ප්රවේශය තරමක් වැඩිදියුණු කිරීමෙන් ඔබට දත්ත හුවමාරුවේ කාර්යක්ෂමතාව වැඩි දියුණු කළ හැකිය. මෙය සිදු කිරීම සඳහා, වෙනස්කම් ලුහුබැඳීම සඳහා තීරු ක්ෂේත්ර අගයන් ලෙස අපි පූර්ණ සංඛ්යා වර්ගය (දිගු නිඛිල) භාවිතා කරන්නෙමු. අපි තීරුව නම් කරමු row_ver
. වාර්තාවක් සාදන විට/වෙනස් කරන සෑම අවස්ථාවකම මෙම තීරුවේ ක්ෂේත්ර අගය තවමත් සකසා/යාවත්කාලීන කළ යුතුය. නමුත් මෙම අවස්ථාවෙහිදී, ක්ෂේත්රයේ වත්මන් දිනය-කාලය පවරනු නොලැබේ, නමුත් සමහර කවුන්ටරයක අගය, එකකින් වැඩි වේ. එහි ප්රතිඵලයක් වශයෙන්, තීරුව row_ver
අද්විතීය අගයන් අඩංගු වන අතර "ඩෙල්ටා" දත්ත සංදර්ශන කිරීමට පමණක් නොව (පෙර හුවමාරු සැසියේ අවසානයේ සිට දත්ත එකතු කරන ලද / වෙනස් කරන ලද) පමණක් නොව, එය සරලව හා ඵලදායී ලෙස පිටු වලට කැඩීමටද භාවිතා කළ හැක.
ඉහළ මට්ටමේ ප්රතිනිර්මාණය කිරීමේ රාමුව තුළ දත්ත මාරු කිරීමේ ප්රමාණය අවම කිරීමේ අවසාන යෝජිත ක්රමය මට වඩාත්ම ප්රශස්ත හා විශ්වීය ලෙස පෙනේ. අපි එය වඩාත් විස්තරාත්මකව බලමු.
පේළි අනුවාද කවුන්ටරයක් භාවිතයෙන් දත්ත යැවීම
සේවාදායකය/ප්රධාන කොටස ක්රියාත්මක කිරීම
MS SQL සේවාදායකයේ, මෙම ප්රවේශය ක්රියාත්මක කිරීමට විශේෂ තීරු වර්ගයක් ඇත - rowversion
. සෑම දත්ත සමුදායකම කවුන්ටරයක් ඇති අතර එය වාර්තාවක් එක් කරන/වෙනස් කරන සෑම අවස්ථාවකම එකකින් වැඩි වන වගුවක් වැනි තීරුවක් ඇත. rowversion
. මෙම කවුන්ටරයේ අගය එකතු කරන ලද/වෙනස් කළ වාර්තාවේ මෙම තීරුවේ ක්ෂේත්රයට ස්වයංක්රීයව පවරනු ලැබේ. Tarantool DBMS හි සමාන ගොඩනඟන යාන්ත්රණයක් නොමැත. කෙසේ වෙතත්, ටැරන්ටූල්හි එය අතින් ක්රියාත්මක කිරීම අපහසු නැත. මෙය සිදු කරන්නේ කෙසේදැයි බලමු.
පළමුව, කුඩා පාරිභාෂිතය: ටැරන්ටූල් හි වගු අවකාශය ලෙස හැඳින්වේ, සහ වාර්තා ටූපල් ලෙස හැඳින්වේ. ටැරන්ටූල් හි ඔබට අනුපිළිවෙලවල් නිර්මාණය කළ හැකිය. අනුපිළිවෙලවල් යනු ඇණවුම් කරන ලද පූර්ණ සංඛ්යා අගයන් නම් කරන ලද උත්පාදක යන්ත්රවලට වඩා වැඩි දෙයක් නොවේ. එම. අපගේ අරමුණු සඳහා අපට අවශ්ය වන්නේ මෙයයි. පහත අපි එවැනි අනුපිළිවෙලක් සාදන්නෙමු.
Tarantool හි කිසියම් දත්ත සමුදා මෙහෙයුමක් සිදු කිරීමට පෙර, ඔබ පහත විධානය ක්රියාත්මක කළ යුතුය:
box.cfg{}
එහි ප්රතිඵලයක් ලෙස, ටැරන්ටූල් වත්මන් නාමාවලියට දත්ත සමුදා ස්නැප්ෂොට් සහ ගණුදෙණු ලොග ලිවීම ආරම්භ කරයි.
අපි අනුපිළිවෙලක් නිර්මාණය කරමු row_version
:
box.schema.sequence.create('row_version',
{ if_not_exists = true })
විකල්පය if_not_exists
නිර්මාණ ස්ක්රිප්ට් එක කිහිප වතාවක් ක්රියාත්මක කිරීමට ඉඩ දෙයි: වස්තුව පවතී නම්, Tarantool එය නැවත නිර්මාණය කිරීමට උත්සාහ නොකරනු ඇත. මෙම විකල්පය සියලු පසුකාලීන DDL විධානවල භාවිතා වේ.
අපි උදාහරණයක් ලෙස අවකාශයක් නිර්මාණය කරමු.
box.schema.space.create('goods', {
format = {
{
name = 'id',
type = 'unsigned'
},
{
name = 'name',
type = 'string'
},
{
name = 'code',
type = 'unsigned'
},
{
name = 'row_ver',
type = 'unsigned'
}
},
if_not_exists = true
})
මෙන්න අපි අවකාශයේ නම සකස් කරමු (goods
), ක්ෂේත්ර නම් සහ ඒවායේ වර්ග.
Tarantool හි ස්වයං-වර්ධක ක්ෂේත්ර ද අනුපිළිවෙල භාවිතයෙන් නිර්මාණය කර ඇත. ක්ෂේත්ර අනුව ස්වයංක්රීයව වැඩිවන ප්රාථමික යතුරක් නිර්මාණය කරමු id
:
box.schema.sequence.create('goods_id',
{ if_not_exists = true })
box.space.goods:create_index('primary', {
parts = { 'id' },
sequence = 'goods_id',
unique = true,
type = 'HASH',
if_not_exists = true
})
Tarantool දර්ශක වර්ග කිහිපයකට සහය දක්වයි. වඩාත් බහුලව භාවිතා වන දර්ශක වන්නේ නමට අනුරූප ව්යුහයන් මත පදනම් වන TREE සහ HASH වර්ග වේ. TREE යනු වඩාත් බහුකාර්ය දර්ශක වර්ගයයි. එය සංවිධානාත්මක ආකාරයකින් දත්ත ලබා ගැනීමට ඔබට ඉඩ සලසයි. නමුත් සමානාත්මතාවය තෝරාගැනීම සඳහා, HASH වඩාත් සුදුසු වේ. ඒ අනුව, ප්රාථමික යතුර සඳහා HASH භාවිතා කිරීම සුදුසුය (අපි කළේ එයයි).
තීරුව භාවිතා කිරීමට row_ver
වෙනස් කළ දත්ත මාරු කිරීමට, ඔබ මෙම තීරුවේ ක්ෂේත්ර වෙත අනුක්රමික අගයන් බැඳිය යුතුය row_ver
. නමුත් ප්රාථමික යතුර මෙන් නොව, තීරු ක්ෂේත්ර අගය row_ver
නව වාර්තා එකතු කිරීමේදී පමණක් නොව, පවතින ඒවා වෙනස් කිරීමේදීද එකකින් වැඩි විය යුතුය. මේ සඳහා ඔබට ප්රේරක භාවිතා කළ හැකිය. Tarantool හට අභ්යවකාශ ප්රේරක වර්ග දෙකක් ඇත: before_replace
и on_replace
. අභ්යවකාශයේ දත්ත වෙනස් වන සෑම අවස්ථාවකම ප්රේරක ක්රියාත්මක වේ (වෙනස්වීම් වලින් බලපෑමට ලක්වන සෑම ටපල් එකක් සඳහාම, ප්රේරක ශ්රිතයක් දියත් කෙරේ). මෙන් නොව on_replace
, before_replace
-triggers මඟින් ප්රේරකය ක්රියාත්මක කර ඇති ටියුපල් දත්ත වෙනස් කිරීමට ඔබට ඉඩ සලසයි. ඒ අනුව, අවසාන වර්ගයේ ප්රේරක අපට ගැලපේ.
box.space.goods:before_replace(function(old, new)
return box.tuple.new({new[1], new[2], new[3],
box.sequence.row_version:next()})
end)
පහත ප්රේරකය ක්ෂේත්ර අගය ප්රතිස්ථාපනය කරයි row_ver
අනුපිළිවෙලෙහි ඊළඟ අගයට tuple ගබඩා කර ඇත row_version
.
අභ්යවකාශයේ සිට දත්ත උකහා ගැනීමට හැකිවන පරිදි goods
තීරුව මගින් row_ver
, අපි දර්ශකයක් නිර්මාණය කරමු:
box.space.goods:create_index('row_ver', {
parts = { 'row_ver' },
unique = true,
type = 'TREE',
if_not_exists = true
})
දර්ශක වර්ගය - ගස (TREE
), නිසා අපට තීරුවේ ඇති අගයන්හි ආරෝහණ අනුපිළිවෙලින් දත්ත උපුටා ගැනීමට අවශ්ය වනු ඇත row_ver
.
අපි අවකාශයට දත්ත කිහිපයක් එකතු කරමු:
box.space.goods:insert{nil, 'pen', 123}
box.space.goods:insert{nil, 'pencil', 321}
box.space.goods:insert{nil, 'brush', 100}
box.space.goods:insert{nil, 'watercolour', 456}
box.space.goods:insert{nil, 'album', 101}
box.space.goods:insert{nil, 'notebook', 800}
box.space.goods:insert{nil, 'rubber', 531}
box.space.goods:insert{nil, 'ruler', 135}
නිසා පළමු ක්ෂේත්රය ස්වයංක්රීය වර්ධක කවුන්ටරයකි; අපි ඒ වෙනුවට nil පසු කරමු. Tarantool ස්වයංක්රීයව ඊළඟ අගය ආදේශ කරනු ඇත. ඒ හා සමානව, තීරු ක්ෂේත්රවල අගය ලෙස row_ver
ඔබට nil සමත් විය හැක - නැතහොත් අගය කිසිසේත් සඳහන් නොකරන්න, මන්ද මෙම තීරුව අවකාශයේ අවසාන ස්ථානය දරයි.
ඇතුළත් කිරීමේ ප්රතිඵලය පරීක්ෂා කරමු:
tarantool> box.space.goods:select()
---
- - [1, 'pen', 123, 1]
- [2, 'pencil', 321, 2]
- [3, 'brush', 100, 3]
- [4, 'watercolour', 456, 4]
- [5, 'album', 101, 5]
- [6, 'notebook', 800, 6]
- [7, 'rubber', 531, 7]
- [8, 'ruler', 135, 8]
...
ඔබට පෙනෙන පරිදි, පළමු සහ අවසාන ක්ෂේත්ර ස්වයංක්රීයව පුරවනු ලැබේ. දැන් අවකාශයේ වෙනස්කම් පිටුවෙන් පිටුව උඩුගත කිරීම සඳහා කාර්යයක් ලිවීමට පහසු වනු ඇත goods
:
local page_size = 5
local function get_goods(row_ver)
local index = box.space.goods.index.row_ver
local goods = {}
local counter = 0
for _, tuple in index:pairs(row_ver, {
iterator = 'GT' }) do
local obj = tuple:tomap({ names_only = true })
table.insert(goods, obj)
counter = counter + 1
if counter >= page_size then
break
end
end
return goods
end
ශ්රිතය අගය පරාමිතියක් ලෙස ගනී row_ver
, වෙනස්කම් ගොඩබෑම අවශ්ය වන අතර, වෙනස් කළ දත්ත වලින් කොටසක් ආපසු ලබා දෙයි.
ටැරන්ටූල් හි දත්ත නියැදීම දර්ශක හරහා සිදු කෙරේ. කාර්යය get_goods
දර්ශකය අනුව පුනරාවර්තකයක් භාවිතා කරයි row_ver
වෙනස් වූ දත්ත ලබා ගැනීමට. පුනරාවර්තක වර්ගය GT (Greater than, greater than) වේ. මෙයින් අදහස් කරන්නේ පුනරාවර්තකය සම්මත කරන ලද යතුරෙන් ආරම්භ වන දර්ශක අගයන් අනුපිළිවෙලින් ගමන් කරන බවයි (ක්ෂේත්ර අගය row_ver
).
පුනරාවර්තකය ටියුපල් ආපසු ලබා දෙයි. පසුව HTTP හරහා දත්ත මාරු කිරීමට හැකි වීම සඳහා, ටියුපල් පසුව අනුක්රමිකකරණය සඳහා පහසු ව්යුහයකට පරිවර්තනය කිරීම අවශ්ය වේ. උදාහරණය මේ සඳහා සම්මත ශ්රිතය භාවිතා කරයි tomap
. භාවිතා කරනවා වෙනුවට tomap
ඔබට ඔබේම කාර්යය ලිවිය හැකිය. උදාහරණයක් ලෙස, අපට ක්ෂේත්රයක් නැවත නම් කිරීමට අවශ්ය විය හැක name
, ක්ෂේත්රය පසුකර නොයන්න code
සහ ක්ෂේත්රයක් එකතු කරන්න comment
:
local function unflatten_goods(tuple)
local obj = {}
obj.id = tuple.id
obj.goods_name = tuple.name
obj.comment = 'some comment'
obj.row_ver = tuple.row_ver
return obj
end
ප්රතිදාන දත්තවල පිටු ප්රමාණය (එක් කොටසක වාර්තා සංඛ්යාව) විචල්යය මගින් තීරණය කරනු ලැබේ page_size
. උදාහරණයේ අගය page_size
යනු 5. සැබෑ වැඩසටහනකදී, පිටු ප්රමාණය සාමාන්යයෙන් වඩා වැදගත් වේ. එය අභ්යවකාශ ටියුපල් වල සාමාන්ය ප්රමාණය මත රඳා පවතී. දත්ත හුවමාරු කාලය මැනීමෙන් ප්රශස්ත පිටු ප්රමාණය ආනුභවිකව තීරණය කළ හැක. පිටු ප්රමාණය විශාල වන තරමට, යැවීම සහ ලැබීම යන පැති අතර වට සංචාර ගණන කුඩා වේ. මේ ආකාරයෙන් ඔබට වෙනස්කම් බාගත කිරීමේ සමස්ත කාලය අඩු කළ හැකිය. කෙසේ වෙතත්, පිටු ප්රමාණය ඉතා විශාල නම්, අපි නියැදිය අනුක්රමික කිරීමට සේවාදායකයේ වැඩි කාලයක් ගත කරන්නෙමු. එහි ප්රතිඵලයක් ලෙස, සේවාදායකය වෙත එන අනෙකුත් ඉල්ලීම් සැකසීමේ ප්රමාදයන් ඇති විය හැක. පරාමිතිය page_size
වින්යාස ගොනුවෙන් පූරණය කළ හැක. එක් එක් සම්ප්රේෂණ අවකාශය සඳහා, ඔබට එහි අගය සැකසිය හැකිය. කෙසේ වෙතත්, බොහෝ හිස්තැන් සඳහා පෙරනිමි අගය (උදාහරණයක් ලෙස, 100) සුදුසු විය හැක.
අපි කාර්යය ක්රියාත්මක කරමු get_goods
:
tarantool> get_goods(0)
---
- - row_ver: 1
code: 123
name: pen
id: 1
- row_ver: 2
code: 321
name: pencil
id: 2
- row_ver: 3
code: 100
name: brush
id: 3
- row_ver: 4
code: 456
name: watercolour
id: 4
- row_ver: 5
code: 101
name: album
id: 5
...
අපි ක්ෂේත්ර අගය ගනිමු row_ver
අවසාන පේළියේ සිට නැවත කාර්යය අමතන්න:
tarantool> get_goods(5)
---
- - row_ver: 6
code: 800
name: notebook
id: 6
- row_ver: 7
code: 531
name: rubber
id: 7
- row_ver: 8
code: 135
name: ruler
id: 8
...
නැවත වරක්:
tarantool> get_goods(8)
---
- []
...
ඔබට පෙනෙන පරිදි, මේ ආකාරයෙන් භාවිතා කරන විට, ශ්රිතය මඟින් සියලුම අවකාශ වාර්තා පිටුවෙන් පිටුව ලබා දෙයි goods
. අවසාන පිටුව හිස් තේරීමක් අනුගමනය කරයි.
අපි අවකාශයේ වෙනස්කම් කරමු:
box.space.goods:update(4, {{'=', 6, 'copybook'}})
box.space.goods:insert{nil, 'clip', 234}
box.space.goods:insert{nil, 'folder', 432}
අපි ක්ෂේත්ර අගය වෙනස් කර ඇත name
එක් ප්රවේශයක් සඳහා සහ නව ඇතුළත් කිරීම් දෙකක් එකතු කරන ලදී.
අපි අවසාන ක්රියාකාරී ඇමතුම නැවත කියමු:
tarantool> get_goods(8)
---
- - row_ver: 9
code: 800
name: copybook
id: 6
- row_ver: 10
code: 234
name: clip
id: 9
- row_ver: 11
code: 432
name: folder
id: 10
...
කාර්යය වෙනස් කළ සහ එකතු කළ වාර්තා ආපසු ලබා දුන්නේය. එබැවින් කාර්යය get_goods
සලකා බලන අනුරූ ක්රමයේ පදනම වන එහි අවසාන ඇමතුමේ සිට වෙනස් වූ දත්ත ලබා ගැනීමට ඔබට ඉඩ සලසයි.
අපි මෙම ලිපියේ විෂය පථයෙන් පිටත JSON ආකාරයෙන් HTTP හරහා ප්රතිඵල නිකුත් කිරීම තබමු. ඔබට මේ ගැන මෙතැනින් කියවිය හැකිය:
සේවාදායකයාගේ / වහල් කොටස ක්රියාත්මක කිරීම
ලැබෙන පැත්තේ ක්රියාත්මක කිරීම පෙනෙන්නේ කෙසේදැයි බලමු. බාගත කළ දත්ත ගබඩා කිරීම සඳහා ලැබෙන පැත්තේ ඉඩක් සාදන්න:
box.schema.space.create('goods', {
format = {
{
name = 'id',
type = 'unsigned'
},
{
name = 'name',
type = 'string'
},
{
name = 'code',
type = 'unsigned'
}
},
if_not_exists = true
})
box.space.goods:create_index('primary', {
parts = { 'id' },
sequence = 'goods_id',
unique = true,
type = 'HASH',
if_not_exists = true
})
අවකාශයේ ව්යුහය මූලාශ්රයේ අවකාශයේ ව්යුහයට සමාන වේ. නමුත් අපි ලැබුණු දත්ත වෙනත් තැනකට යැවීමට යන්නේ නැති නිසා තීරුව row_ver
ලබන්නාගේ අවකාශයේ නැත. ක්ෂේත්රයේ id
මූලාශ්ර හඳුනාගැනීම් වාර්තා කරනු ලැබේ. එමනිසා, ග්රාහක පැත්තේ එය ස්වයංක්රීයව වැඩි කිරීම අවශ්ය නොවේ.
ඊට අමතරව, අගයන් සුරැකීමට අපට ඉඩක් අවශ්ය වේ row_ver
:
box.schema.space.create('row_ver', {
format = {
{
name = 'space_name',
type = 'string'
},
{
name = 'value',
type = 'string'
}
},
if_not_exists = true
})
box.space.row_ver:create_index('primary', {
parts = { 'space_name' },
unique = true,
type = 'HASH',
if_not_exists = true
})
එක් එක් පටවන ලද අවකාශය සඳහා (ක්ෂේත්රය space_name
) අපි අවසන් වරට පටවන ලද අගය මෙහි සුරකිමු row_ver
(ක්ෂේත්ර value
) තීරුව මූලික යතුර ලෙස ක්රියා කරයි space_name
.
අභ්යවකාශ දත්ත පූරණය කිරීමට ශ්රිතයක් නිර්මාණය කරමු goods
HTTP හරහා. මෙය සිදු කිරීම සඳහා, අපට HTTP සේවාදායකයක් ක්රියාත්මක කරන පුස්තකාලයක් අවශ්ය වේ. පහත පේළිය පුස්තකාලය පූරණය කරන අතර HTTP සේවාලාභියා ක්ෂණික කරයි:
local http_client = require('http.client').new()
අපට json deserialization සඳහා පුස්තකාලයක් ද අවශ්ය වේ:
local json = require('json')
දත්ත පැටවීමේ කාර්යයක් සෑදීමට මෙය ප්රමාණවත් වේ:
local function load_data(url, row_ver)
local url = ('%s?rowVer=%s'):format(url,
tostring(row_ver))
local body = nil
local data = http_client:request('GET', url, body, {
keepalive_idle = 1,
keepalive_interval = 1
})
return json.decode(data.body)
end
ශ්රිතය url ලිපිනයට HTTP ඉල්ලීමක් ක්රියාත්මක කර එය යවයි row_ver
පරාමිතියක් ලෙස සහ ඉල්ලීමේ deserialized ප්රතිඵලය ලබා දෙයි.
ලැබුණු දත්ත සුරැකීමේ කාර්යය මේ ආකාරයෙන් පෙනේ:
local function save_goods(goods)
local n = #goods
box.atomic(function()
for i = 1, n do
local obj = goods[i]
box.space.goods:put(
obj.id, obj.name, obj.code)
end
end)
end
අවකාශයට දත්ත සුරැකීමේ චක්රය goods
ගනුදෙනුවක තබා ඇත (මේ සඳහා ශ්රිතය භාවිතා වේ box.atomic
) තැටි මෙහෙයුම් සංඛ්යාව අඩු කිරීමට.
අවසාන වශයෙන්, දේශීය අවකාශය සමමුහුර්ත කිරීමේ කාර්යය goods
ප්රභවයක් සමඟ ඔබට එය මේ ආකාරයට ක්රියාත්මක කළ හැකිය:
local function sync_goods()
local tuple = box.space.row_ver:get('goods')
local row_ver = tuple and tuple.value or 0
—— set your url here:
local url = 'http://127.0.0.1:81/test/goods/list'
while true do
local goods = load_goods(url, row_ver)
local count = #goods
if count == 0 then
return
end
save_goods(goods)
row_ver = goods[count].rowVer
box.space.row_ver:put({'goods', row_ver})
end
end
මුලින්ම අපි කලින් save කරපු අගය කියවමු row_ver
අවකාශය සඳහා goods
. එය අතුරුදහන් වී ඇත්නම් (පළමු හුවමාරු සැසිය), එවිට අපි එය ලෙස ගනිමු row_ver
ශුන්ය. චක්රයේ මීළඟට අපි නිශ්චිත url හි මූලාශ්රයෙන් වෙනස් කරන ලද දත්ත පිටුවෙන් පිටුව බාගැනීමක් සිදු කරන්නෙමු. සෑම පුනරාවර්තනයකදීම, අපි ලැබුණු දත්ත සුදුසු ප්රාදේශීය අවකාශයට සුරකිමු සහ අගය යාවත්කාලීන කරන්නෙමු row_ver
(අභ්යවකාශයේ row_ver
සහ විචල්යයේ row_ver
) - අගය ගන්න row_ver
පටවන ලද දත්තවල අවසාන පේළියෙන්.
අහම්බෙන් ලූපයෙන් ආරක්ෂා වීමට (වැඩසටහනේ දෝෂයක් ඇති විට), ලූපය while
මගින් ප්රතිස්ථාපනය කළ හැකිය for
:
for _ = 1, max_req do ...
කාර්යය ක්රියාත්මක කිරීමේ ප්රතිඵලයක් ලෙස sync_goods
අවකාශය goods
ග්රාහකයේ සියලුම අභ්යවකාශ වාර්තා වල නවතම අනුවාද අඩංගු වේ goods
මූලාශ්රය තුළ.
පැහැදිලිවම, දත්ත මකාදැමීම මේ ආකාරයෙන් විකාශනය කළ නොහැක. එවැනි අවශ්යතාවයක් තිබේ නම්, ඔබට මකාදැමීමේ සලකුණක් භාවිතා කළ හැකිය. අවකාශයට එකතු කරන්න goods
බූලියන් ක්ෂේත්රය is_deleted
සහ වාර්තාවක් භෞතිකව මකා දැමීම වෙනුවට, අපි තාර්කික මකාදැමීම භාවිතා කරමු - අපි ක්ෂේත්ර අගය සකස් කරමු is_deleted
අර්ථයට true
. සමහර විට බූලියන් ක්ෂේත්රයක් වෙනුවට is_deleted
ක්ෂේත්රය භාවිතා කිරීම වඩාත් පහසු වේ deleted
, වාර්තාව තාර්කිකව මකාදැමීමේ දිනය-කාලය ගබඩා කරයි. තාර්කික මකාදැමීමක් සිදු කිරීමෙන් පසු, මකාදැමීම සඳහා ලකුණු කර ඇති වාර්තාව මූලාශ්රයෙන් ගමනාන්තයට මාරු කරනු ලැබේ (ඉහත සාකච්ඡා කළ තර්කයට අනුව).
අනුක්රමය row_ver
වෙනත් අවකාශයන්ගෙන් දත්ත සම්ප්රේෂණය කිරීමට භාවිතා කළ හැක: එක් එක් සම්ප්රේෂණය කරන ලද අවකාශය සඳහා වෙනම අනුපිළිවෙලක් සෑදීමට අවශ්ය නොවේ.
අපි Tarantool DBMS භාවිතා කරන යෙදුම්වල ඉහළ මට්ටමේ දත්ත අනුවර්තනය කිරීමේ ඵලදායී ක්රමයක් දෙස බැලුවෙමු.
සොයා ගැනීම්
- Tarantool DBMS යනු ඉහළ පැටවුම් යෙදුම් නිර්මාණය කිරීම සඳහා ආකර්ෂණීය, පොරොන්දු වූ නිෂ්පාදනයකි.
- ඉහළ මට්ටමේ දත්ත අනුකරණයට පහත් මට්ටමේ අනුවර්තනයට වඩා වාසි ගණනාවක් ඇත.
- ලිපියේ සාකච්ඡා කර ඇති ඉහළ මට්ටමේ අනුවර්තන ක්රමය මඟින් පසුගිය හුවමාරු සැසියේ සිට වෙනස් වූ වාර්තා පමණක් මාරු කිරීමෙන් මාරු කළ දත්ත ප්රමාණය අවම කිරීමට ඔබට ඉඩ සලසයි.
මූලාශ්රය: www.habr.com