O'zingizning monolitingizdan bitta jadval merosxo'rligini qanday olib tashlash mumkin

Meros olish oson - texnik qarz va soliqlarni to'lash kerak bo'lmaguncha.

Besh yil oldin Learn asosiy kod bazasi paydo bo'lganida, Yagona jadval merosxo'rligi (STI) juda mashhur edi. O'sha paytda Flatiron laboratoriyalari jamoasi bu ishni davom ettirishdi - undan hamma narsa uchun foydalanib, baholash va o'quv dasturlaridan tortib to o'sib borgan ta'limni boshqarish tizimimizdagi voqealar va tarkiblar uchun. Va bu juda yaxshi bo'ldi - ish tugadi. Bu o'qituvchilarga o'quv dasturlarini taqdim etish, talabalar yutuqlarini kuzatish va qiziqarli foydalanuvchi tajribasini yaratish imkonini berdi.

Ammo ko'plab bloglar ta'kidlaganidek (bu, bittasi, masalan, bittasi), STI juda katta hajmga ega emas, ayniqsa ma'lumotlar o'sib borishi va yangi kichik sinflar o'zlarining superklasslari va bir-birlaridan juda farq qilishi bilan. Siz taxmin qilganingizdek, xuddi bizning kod bazamizda ham shunday bo'ldi! Maktabimiz kengaydi va biz ko'proq xususiyatlar va dars turlarini qo'llab-quvvatladik. Vaqt o'tishi bilan modellar shishiradi va mutatsiyaga uchraydi va endi domen uchun to'g'ri mavhumlikni aks ettirmaydi.

Biz o'sha joyda bir muncha vaqt yashadik va unga kodni keng berdik va faqat kerak bo'lganda uni yamoqdamiz. Va keyin reflektor vaqti keldi.

So'nggi bir necha oy ichida men bir muncha noaniq nomlangan "Kontent" modelini o'z ichiga olgan, ayniqsa o'ta xavfli STI misolini olib tashlash vazifasini boshladim. STIni dastlab sozlash juda oson, uni olib tashlash juda qiyin.

Shunday qilib, ushbu postda men STI haqida bir oz ma'lumot beraman, bizning domenimiz haqida ba'zi bir ma'lumotni beraman, ish hajmini bayon qilaman va men yadroni siqib chiqarganimda jiddiy zararni kamaytirish uchun yuza maydonini minimallashtirishda o'zgarishlarni xavfsiz joylashtirish uchun ishlatgan strategiyalarimni muhokama qilaman. bizning ilova.

Yagona jadval merosxo'rligi (STI) haqida

Qisqacha aytganda, bitta jadvalda relslar jadvallari bir nechta turdagi darslarni bitta jadvalda saqlashga imkon beradi. Active Record-da sinf nomi jadvalning turi sifatida saqlanadi. Masalan, sizda Lab, Readme va Project bo'lishi mumkin, ularning barchasi tarkibiy jadvalda mavjud:

sinf laboratoriyasi 

Ushbu misolda laboratoriyalar, readmes va loyihalar dars bilan bog'liq bo'lishi mumkin bo'lgan barcha turdagi tarkibiy qismlardan iborat.

Tarkiblar jadvalining sxemasi xuddi shunday ko'rinishga ega edi, shunda siz ushbu jadval faqat jadvalda saqlanganligini ko'rishingiz mumkin.

create_table "content", kuch:: kaskad qilish | t |
  t.integer "o'quv dasturi_id",
  t.string "turi",
  "Markdown_format" matni,
  t.string "sarlavha",
  t.integer "track_id",
  t.integer "github_repository_id"
oxiri

Ish doirasini aniqlash

Tarkib ba'zan chalkash holda, ilova bo'ylab tarqalib ketdi. Masalan, bu "Lesson" modelidagi munosabatlarni tavsiflaydi.

sinf Dars  {tartib (tartibli:: asc)}
  has_one: tarkib, xorijiy_key:: o'quv dasturi_id
  has_many: readmes, Foreign_key:: o'quv dasturi_id
  has_one: lab, Foreign_key:: o'quv dasturi_id
  has_one: readme, Foreign_key:: o'quv dasturi_id
  has_many: tayinlangan_repos, orqali:: tarkib
oxiri

Xijolat bo'ldimi? Men ham shunday edim va bu men o'zgartirishim kerak bo'lgan ko'pchilikning faqat bitta namunasi edi.

Shunday qilib, mening ajoyib va ​​iqtidorli jamoadoshlarim (Kate Travers, Stiven Nunez va Spenser Rojers) bilan men chalkashlikni kamaytirishga va ushbu tizimni osonlashtirishga yordam beradigan yaxshiroq dizaynni taklif qildim.

Yangi dizayn

Tarkibni namoyish etishga harakat qilayotgan tushuncha GithubRepozitariya va Dars o'rtasidagi vositachi edi.

Har bir "kanonik" dars mazmuni GitHub-dagi ombor bilan bog'langan. Darslar nashr etilganda yoki o'quvchilarga "tarqatilganda" biz ushbu GitHub omborining nusxasini yaratamiz va talabalarga unga havola beramiz. Dars va tarqatilgan versiya o'rtasidagi bog'liqlik AssignedRepo deb nomlanadi.

Shunday qilib, darslarning ikkala uchida ham GitHub omborlari mavjud: kanonik versiya va joylashtirilgan versiya.

sinf tarkibidagi 
class AssignedRepo 

Bir vaqtning o'zida darslar bir nechta tarkibga ega bo'lishlari mumkin edi, ammo bizning hozirgi dunyomizda bunday bo'lmaydi. Buning o'rniga, turli xil darslar mavjud bo'lib, ular o'zlarining shaxsiy omborlariga kiritilgan fayllarni ko'rib chiqishlari mumkin.

Shunday qilib, biz qaror qildik, tarkibni CanonicalMaterial deb nomlangan yangi kontseptsiya bilan almashtirdik va AssignedRepo-ga to'g'ridan-to'g'ri bog'langan darsga to'g'ridan-to'g'ri havolani berib o'ting.

Eski yangi tizim diagrammasida qizil nuqta bilan chiziqlar eskirish uchun belgilangan yo'llarni bildiradi

Agar bu chalkash va juda ko'p ishlarga o'xshab ko'rinadigan bo'lsa, chunki bu. Eng asosiy yutuq shuki, biz juda katta kod bazasida modelni almashtirishimiz kerak edi va shu bilan 6000 kod qatorida biron bir joyda o'zgarib qoldik.

Eng asosiy yutuq shuki, biz juda katta kod bazasida modelni almashtirishimiz kerak edi va shu bilan 6000 kod qatorida biron bir joyda o'zgarib qoldik.

Qayta tiklash va STIni almashtirish strategiyalari

Yangi model

Birinchidan, biz canonical_materials deb nomlangan yangi jadval yaratdik va yangi model va birlashmalar yaratdik.

sinf CanonicalMaterial 

Shuningdek, biz o'quv dasturlari jadvaliga canonical_material_id tashqi kalitini qo'shdik, shunda dars unga havolani saqlab qolishi mumkin.

Belgilangan_repos jadvaliga biz dars_id ustunini qo'shdik.

Ikkilik yozuvlar

Yangi jadvallar va ustunlar mavjud bo'lgandan so'ng, biz bir vaqtning o'zida zaxira to'ldirish vazifasini bajarmaslik uchun eski jadvallarga va yangilariga yozishni boshladik. Kontent qatorini yaratish yoki yangilash uchun biron bir harakat qilganingizda, biz ham canonical_material yaratamiz yoki yangilaymiz.

Masalan:

dars.build_content (
  'repo_name' => repo.name,
  'github_repository_id' => repo_id,
  'markdown_format' => repo.readme
)

dars.canonical_material = repo.canonical_material
dars.save

Bu tarkibni oxir-oqibat olib tashlash uchun asos yaratishga imkon berdi.

Qayta to'ldirish

Jarayonning keyingi bosqichi ma'lumotlarni zaxira qilish edi. Biz jadvallarimizni to'ldirish va har bir GithubRepozitory uchun CanonicalMaterial mavjudligini va har bir darsda CanonicalMateryali bo'lishini ta'minlash uchun rake topshiriqlarini yozdik. Va keyin biz ishlab chiqarish serverida vazifalarni bajardik.

Qayta ishlab chiqarishning ushbu turida biz eski ma'lumotlarga ega bo'lish uchun toza tanaffus qilishimiz uchun ishonchli ma'lumotlarga ega bo'lishni afzal ko'rdik. Yana bir hayotiy imkoniyat, bu hali ham eski modellarni qo'llab-quvvatlaydigan kod yozishdir. Bizning tajribamizda eski ma'lumotlarga asoslangan ma'lumotni qayta to'ldirish va haqiqiyligini tekshirishga qaraganda, eski fikrlashni qo'llab-quvvatlaydigan kodni saqlash ancha chalkash va qimmatga tushdi.

Bizning tajribamizda eski ma'lumotlarga asoslangan ma'lumotni qayta to'ldirish va haqiqiyligini tekshirishga qaraganda, eski fikrlashni qo'llab-quvvatlaydigan kodni saqlash ancha chalkash va qimmatga tushdi.

O'zgartirish

Va keyin quvnoq qism boshlandi. O'zgartirishni iloji boricha xavfsiz qilish uchun biz quyi kodni kichik PRlarda yuborish uchun xususiyat bayroqlaridan foydalandik, bu bizga tezkor aloqa halqasini yaratishga va narsalar buzilishini tezroq bilib olishga imkon berdi. Buning uchun biz standart xususiyatlarni ishlab chiqish uchun foydalanadigan taqinchoqlardan foydalandik.

Nimani qidirish kerak

O'zgartirishni amalga oshirishning eng qiyin qismlaridan biri bu ko'p narsalarni izlash edi. "Tarkib" so'zi, afsuski, juda umumiydir, shuning uchun oddiy, global qidirish va almashtirishni amalga oshirishning iloji bo'lmadi, shuning uchun men turli xil o'zgarishlarni hisobga olishga intilgan holda keng qamrovli qidirishga moyil bo'ldim.

STIni olib tashlashda quyidagilarni izlash kerak:

  • Modelning yakka va ko'plik shakllari, uning barcha kichik sinflari, usullari, yordamchi usullari, assotsiatsiyalari va so'rovlari.
  • Qattiq kodli SQL so'rovlari
  • Nazoratchilar
  • Serializatorlar
  • Ko'rishlar

Masalan, tarkib uchun, quyidagini qidirishni anglatadi

  • : tarkib - assotsiatsiyalar va so'rovlar uchun
  • : tarkib - assotsiatsiyalar va so'rovlar uchun
  • .joins (: tarkib) - oldingi qidiruv orqali qidirib topilgan qo'shilish so'rovlari uchun
  • .includes (: tarkib) - oldingi qidiruv orqali qo'lga olinishi kerak bo'lgan ikkinchi darajali birlashmalarga yuklash uchun
  • tarkib: - joylashtirilgan so'rovlar uchun
  • tarkib: - yana, ko'proq joylashtirilgan so'rovlar
  • content_id - to'g'ridan-to'g'ri id bo'yicha so'rovlar uchun
  • .content - usul qo'ng'iroqlari
  • .contents - yig'ish usuli qo'ng'iroqlari
  • .build_content - foydali usul has_one tomonidan qo'shilgan va assotsiatsiyaga tegishli
  • .create_content - has_one tomonidan qo'shilgan yordamchi usul va assotsiatsiyaga tegishli
  • .content_ids - has_many birlashmasi tomonidan qo'shilgan yordamchi usul
  • Tarkib - sinf nomining o'zi
  • tarkib - har qanday qattiq kodlangan havolalar yoki SQL so'rovlari uchun oddiy satr

Men bu tarkib uchun juda batafsil ro'yxat ekanligiga ishonaman. Va keyin men laboratoriya, o'qish va loyiha uchun xuddi shunday qildim. Ko'rinib turibdiki, Rels juda moslashuvchan va ko'plab yordamchi usullarni qo'shganligi sababli, model foydalanishni tugatadigan barcha joylarni topish qiyin.

Qanday qilib qo'ng'iroq qiluvchilarni topganingizdan so'ng, amalda qanday qilib o'zgartiriladi

Siz almashtirish yoki o'chirishga harakat qilayotgan modelning barcha qo'ng'iroq saytlarini haqiqatan ham aniqlagandan so'ng, siz narsalarni qayta yozishingiz kerak. Umuman olganda, biz kuzatgan jarayon

  1. Aniqlashda usulning holatini o'zgartiring yoki qo'ng'iroq joyida usulni o'zgartiring
  2. Yangi usullarni yozing va ularni qo'ng'iroq saytida maxsus bayroq orqasida chaqiring
  3. Usullar bilan birlashmalarga bog'liqlikni buzish
  4. Agar usul haqida ishonchingiz komil bo'lmasa, xususiyatlar bayrog'ining orqasida xatolarni oshiring
  5. Xuddi shu interfeysga ega ob'ektlarni almashtirish

Bu erda har bir strategiya misollari keltirilgan.

1a. Usul harakati yoki so'rovni o'zgartiring

Ba'zi almashtirishlar juda sodda. Siz "ushbu bayroq yoqilganda boshqa kod o'rniga bu kodni chaqiring" deb aytish uchun xususiyat bayroqchasini qo'yasiz.

Shunday qilib, tarkibga asoslangan so'rov o'rniga, bu erda biz canonical_materialga asoslangan so'rovni qilamiz.

1b. Qo'ng'iroq joyida usulni o'zgartiring

Ba'zida chaqirilayotgan usullarni standartlashtirish uchun qo'ng'iroq joyida usulni almashtirish osonroq. (Siz buni amalga oshirganingizda test to'plamingizni ishga tushirishingiz va / yoki testlarni yozishingiz kerak.) Buni amalga oshirish, keyingi qayta tiklashga yo'l ochishi mumkin.

Ushbu misol Canonical_id ustuniga bog'liqlikni qanday yo'q qilish kerakligini ko'rsatmoqda, bu endi yo'q. E'tibor bering, biz chaqiruv saytida usulni bayroq orqasida qo'ymasdan almashtirdik. Ushbu qayta faollashtirishda biz canonical_id-ni bir nechta joyda yig'ib qo'yganimizni payqadik, shuning uchun boshqa so'rovlarga zanjir qo'yishimiz mumkin bo'lgan mantiqiy usulni to'ldirdik. Qo'ng'iroq qilish joyidagi usul o'zgartirildi, lekin xususiyat bayrog'i yoqilmaguncha xatti-harakatlar o'zgarmadi.

2. Yangi usullarni yozing va ularni qo'ng'iroq joyida maxsus bayroq orqasida chaqiring

Ushbu strategiya usulni almashtirish bilan bog'liq, faqat shu usulda biz yangi usul yozamiz va uni qo'ng'iroq saytida xususiyat bayrog'i orqasida chaqiramiz. Bu faqat bitta joyda chaqiriladigan usul uchun ayniqsa foydali edi. Shuningdek, bu usul bizga har doim ham foydali bo'lgan imzoni yaxshiroq berishimizga yordam berdi.

3. Birlashmalarga bog'liqlik usullarini sindirish

Ushbu keyingi misolda trekka ega_many laboratoriyalari. Has_many assotsiatsiyasi yordamchi usullarni qo'shishini bilganimiz sababli, biz eng keng tarqalgan deb nomlangan va has_many: labs liniyasini olib tashladik. Ushbu usul bir xil interfeysga mos keladi, shuning uchun xususiyat yoqilgunga qadar usulni chaqiradigan har qanday narsa ishlashni davom ettiradi.

4. Agar usul haqida ishonchingiz komil bo'lmasa, xususiyatlar bayrog'i orqasida xatolarni oshiring

Ba'zi paytlar biz qo'ng'iroq saytini o'tkazib yuborganimizga amin emas edik. Shunday qilib, dastavval shunchaki qiyin usullarni olib tashlashning o'rniga, biz qo'lda sinov bosqichida ularni ushlab qolishimiz uchun xatolarni ataylab oshirdik. Bu bizga usul chaqirilayotgan joyni kuzatishning yaxshiroq yo'lini berdi.

5. Bir xil interfeysga ega bo'lgan ob'ektlarni almashtirish

Laboratoriya assotsiatsiyasidan xalos bo'lishni istaganimiz sababli, laboratoriya bajarilishini qayta yozdikmi? usuli. Laboratoriya yozuvining mavjudligini tekshirishning o'rniga, biz canonical_materialni almashtirdik, qo'ng'iroqni topshirdik va ob'ektni xuddi shu usulga javob berdik.

Bular qaramlikni yo'qotish va Rails monolitimiz davomida yangi ob'ektlarni almashtirish uchun eng foydali strategiyalar edi. Yuzlab ta'riflar va qo'ng'iroq saytlarini ko'rib chiqqandan so'ng, biz ularni birma-bir almashtirdik yoki qayta yozdik. Bu men hech kimni xohlamaydigan juda zerikarli jarayon, lekin oxir-oqibat bizning kod bazamizni yanada tushunarli qilish va hech narsa qilmay o'tirgan eski kodni olib tashlash uchun juda foydali bo'ldi. Sochni tarash uchun bir necha hafta kerak bo'ldi, ammo biz ko'plab ma'lumotnomalarni almashtirganimizdan so'ng, biz qo'lda tekshirishni boshladik.

Sinov va qo'lda sinov

O'zgarishlar butun kodlar bazasidagi xususiyatlarga ta'sir qilganligi sababli, ularning ba'zilari sinovdan o'tkazilmagan, aniqlik bilan QA qilish qiyin edi, ammo biz qo'limizdan kelganini qildik. Biz QA serverimizda qo'lda sinov o'tkazdik, natijada juda ko'p xato va holatlar yuzaga keldi. Va keyin biz yanada muhim yo'llar uchun oldinga va yangi sinovlarni yozdik.

Tugatish, jonli efir va tozalash

QA-ni topshirganimizdan so'ng, biz o'zimizning bayroqchamizni osib qo'ydik va tizimni o'rnatishga ruxsat berdik. Barqaror ekanligiga ishonch hosil qilganimizdan so'ng, xususiyatlar bayroqlari va eski kod yo'llarini kod bazasidan olib tashladik. Afsuski, bu kutilganidan ko'ra qiyinroq edi, chunki u ko'plab sinov dasturlarini, asosan Kontent modeliga ishonadigan fabrikalarni qayta yozishni talab qildi. O'tmishda, biz qayta ishlash paytida ikkita to'plam testini yozishimiz mumkin edi, bittasi hozirgi kod uchun va ikkinchisi xususiyat bayrog'i ortidagi kod uchun.

Yakuniy qadam sifatida, hanuzgacha biz ma'lumotlarni zaxiralashimiz va foydalanilmagan jadvallarimizni tashlab yuborishimiz kerak.

Va do'stlar, bu sizning Rails monolitidagi yagona stol merosxo'rligidan xalos bo'lishning bir usuli. Ehtimol, ushbu misol sizga ham yordam beradi.

Sizda STIni yo'q qilish yoki qayta davolashning boshqa usullari bormi? Biz bilishga qiziqamiz. Izohlarda bizga xabar bering.

Shuningdek, biz yollanamiz! Bizning jamoamizga qo'shiling. Va'da beraman.

Resurslar va qo'shimcha o'qish

  • Rels qo'llanmalari meros
  • Eugene Vang tomonidan relslarda bitta stol merosxo'rligini qanday va qachon ishlatish (Flatiron Grad!)
  • Bizning relslar ilovamizni bitta jadvalli merosdan tashqarida qayta tiklash
  • Reyslardagi polimorfik assotsiatsiyalar va boshqalar
  • Reyslardan foydalanib bitta jadvalli merosxo'rlik 5.02

Flatiron maktabi haqida ko'proq ma'lumot olish uchun veb-saytga tashrif buyuring, Facebook va Twitter-da bizni kuzatib boring va sizga yaqin bo'lgan tadbirlarda bizni kuzatib boring.

Flatiron maktabi - WeWork oilasining faxrli a'zosi. WeWork Technology va Mitingup texnologik bloglarimizni ko'rib chiqing.