Mysql
 sql >> база данни >  >> RDS >> Mysql

Подходи за разделяне на MySQL?

Най-добрият подход за разделяне на MySQL таблици да не го правите, освен ако не е напълно неизбежно да го направите.

Когато пишете приложение, обикновено искате да го направите по начин, който увеличава максимално скоростта, скоростта на разработчика. Оптимизирате за латентност (време, докато отговорът е готов) или пропускателна способност (брой отговори на единица време) само когато е необходимо.

Разделяте и след това присвоявате дялове на различни хостове (=шард) само когато сумата от всички тези дялове вече не се вписва в един екземпляр на сървър на база данни - причината за това е или запис, или четене.

Случаят на запис е или а) честотата на записите претоварва постоянно дисковете на този сървър или б) има твърде много записи, така че репликацията постоянно изостава в тази йерархия на репликация.

Случаят за четене за разделяне е, когато размерът на данните е толкова голям, че работният набор от тях вече не се вписва в паметта и четените данни започват да удрят диска, вместо да се обслужват от паметта през повечето време.

Само когато имаше за да разделиш го направи.

В момента, в който разделите, вие плащате за това по няколко начина:

Голяма част от вашия SQL вече не е декларативен.

Обикновено в SQL казвате на базата данни какви данни искате и оставяте на оптимизатора да превърне тази спецификация в програма за достъп до данни. Това е хубаво нещо, защото е гъвкаво и защото писането на тези програми за достъп до данни е скучна работа, която вреди на скоростта.

С разчленена среда вероятно свързвате таблица на възел A срещу данни на възел B или имате таблица, по-голяма от възел, на възли A и B и свързвате данни от нея с данни, които са на възел B и C. Започвате да пишете ръчно базирани на хеш решения за присъединяване от страна на приложението, за да разрешите това (или преоткривате MySQL клъстер), което означава, че в крайна сметка получавате много SQL, който вече не е декларативен, но изразява SQL функционалност по процедурен начин (например използвате изрази SELECT в цикли).

Имате голямо забавяне на мрежата.

Обикновено SQL заявка може да бъде разрешена локално и оптимизаторът знае за разходите, свързани с достъпа до локален диск, и разрешава заявката по начин, който минимизира разходите за това.

В разчленена среда заявките се разрешават или чрез извършване на достъпи ключ-стойност в мрежата до множество възли (надявам се с пакетен достъп до ключове, а не индивидуални търсения на ключ за двупосочно пътуване) или чрез натискане на части от WHERE клауза нататък към възлите, където могат да бъдат приложени (това се нарича „избутване на условието“) или и двете.

Но дори и в най-добрите случаи това включва много повече мрежови двупосочни пътувания в сравнение с местната ситуация и е по-сложно. Особено след като MySQL оптимизаторът изобщо не знае нищо за латентността на мрежата (Добре, MySQL клъстерът бавно се подобрява в това, но за ванилия MySQL извън клъстера това все още е вярно).

Губите много изразителна сила на SQL.

Добре, това вероятно е по-малко важно, но ограниченията на външния ключ и други SQL механизми за целостта на данните не са в състояние да обхващат множество фрагменти.

MySQL няма API, който позволява асинхронни заявки, които са в работно състояние.

Когато данни от един и същи тип се намират на множество възли (например потребителски данни на възли A, B и C), хоризонталните заявки често трябва да бъдат разрешени спрямо всички тези възли („Намерете всички потребителски акаунти, които не са били влезли в продължение на 90 дни или по"). Времето за достъп до данни нараства линейно с броя на възлите, освен ако няколко възли не могат да бъдат запитани паралелно и резултатите да се обобщят при постъпването им („Намаляване на картата“).

Предпоставката за това е API за асинхронна комуникация, който не съществува за MySQL в добра работна форма. Алтернативата е много разклонения и връзки в детските процеси, които посещават света на смученето на сезонна карта.

След като започнете да споделяте, структурата на данните и мрежовата топология стават видими като точки за производителност към вашето приложение. За да работи сравнително добре, приложението ви трябва да е наясно с тези неща, а това означава, че наистина само разделянето на ниво приложение има смисъл.

Въпросът е повече, ако искате да разделите автоматично (определяне кой ред влиза в кой възел чрез хеширане на първични ключове например) или ако искате да разделите функционално по ръчен начин („Таблиците, свързани с потребителската история на xyz, отиват на това master, докато свързаните с abc и def таблици отиват към този главен елемент").

Функционалното разделяне има предимството, че ако се направи правилно, то е невидимо за повечето разработчици през повечето време, тъй като всички таблици, свързани с тяхната потребителска история, ще бъдат достъпни локално. Това им позволява да продължат да се възползват от декларативния SQL възможно най-дълго и също така ще имат по-малко мрежово забавяне, тъй като броят на междумрежовите трансфери е минимален.

Функционалното разделяне има недостатъка, че не позволява нито една таблица да бъде по-голяма от един екземпляр и изисква ръчно внимание от дизайнер.

Функционалното разделяне има предимството, че се прави относително лесно към съществуваща кодова база с редица промени, които не са прекалено големи. http://Booking.com го е правил няколко пъти през последните години и им се е отразило добре.

След като казах всичко това, разглеждайки въпроса ви, вярвам, че задавате грешни въпроси или напълно не разбирам твърдението ви за проблема.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Сравняване на Percona XtraBackup с MySQL Enterprise Backup:Част първа

  2. Изпълнение на .sql скрипт с помощта на MySQL с JDBC

  3. Как да съединя две таблици mysql?

  4. Отказ и отказ на Amazon RDS

  5. Може ли приложение за Android да се свърже директно с онлайн база данни на mysql