14 рэчаў, якія я хацеў бы ведаць перад пачаткам працы з MongoDB

Пераклад артыкула падрыхтаваны напярэдадні старту курса "Нерэляцыйныя базы дадзеных".

14 рэчаў, якія я хацеў бы ведаць перад пачаткам працы з MongoDB

Асноўныя моманты:

  • Вельмі важна распрацаваць схему нягледзячы на ​​тое, што ў MongoDB яна неабавязковая.
  • Аналагічна, азначнікі павінны адпавядаць вашай схеме і шаблонамі доступу.
  • Пазбягайце выкарыстання вялікіх аб'ектаў і вялікіх масіваў.
  • Будзьце асцярожныя з наладамі MongoDB, асабліва калі гаворка ідзе аб бяспецы і надзейнасці.
  • У MongoDB няма аптымізатара запытаў, таму вы павінны быць асцярожныя пры выкананні аперацый запыту.

Я вельмі даўно працую з базамі дадзеных, але толькі нядаўна адчыніў для сябе MongoDB. Ёсць некалькі рэчаў, якія я хацеў бы ведаць перад пачаткам працы з ёй. Калі ў чалавека ўжо ёсць вопыт у пэўнай сферы, у яго існуюць прадузятыя ўяўленні аб тым, што такое базы даных і што яны робяць. У надзеі аблегчыць задачу разумення іншым людзям, прадстаўляю спіс распаўсюджаных памылак.

Стварэнне сервера MongoDB без аўтэнтыфікацыі

Нажаль, MongoDB па змаўчанні ставіцца без аўтэнтыфікацыі. Для рабочай станцыі, доступ да якой устанаўліваецца лакальна, такая практыка нармальная. Але паколькі MongoDB - гэта шматкарыстальніцкая сістэма, якая любіць выкарыстоўваць вялікія аб'ёмы памяці, будзе лепш, калі вы паставіце яе на сервер з максімальна магчымай у вашых умовах колькасцю аператыўнай памяці, нават калі збіраецеся выкарыстоўваць яе толькі для распрацоўкі. Усталяванне на сервер праз порт па змаўчанні можа апынуцца праблемнай, асабліва, калі ў запыце можна выканаць любы код на javascript (напрыклад, $where у якасці ідэі для ін'екцыі).

Ёсць некалькі метадаў аўтэнтыфікацыі, але прасцей за ўсё ўсталяваць для карыстача ID/пароль. Скарыстайцеся гэтай ідэяй, пакуль будзеце думаць над мудрагелістай аўтэнтыфікацыяй на аснове LDAP. Калі казаць аб бяспецы, то MongoDB павінна ўвесь час абнаўляцца, а логі заўсёды варта правяраць на наяўнасць несанкцыянаванага доступу. Мне, напрыклад, падабаецца выбіраць іншы порт у якасці порта па змаўчанні.

Не забудзьцеся прывязаць паверхню нападу да MongoDB

Чэк-ліст забеспячэння бяспекі MongoDB змяшчае добрыя парады для зніжэння рызыкі пранікнення ў сетку і ўцечкі дадзеных. Лёгка адмахнуцца і сказаць, што сервер для распрацоўкі не мае патрэбы ў высокім узроўні бяспекі. Аднак усё не так проста і гэта ставіцца да ўсіх сервераў MongoDB. У прыватнасці, калі няма важкай прычыны выкарыстоўваць mapReduce, group або $where, трэба адключыць выкарыстанне адвольнага кода на JavaScript, напісаўшы ў файле канфігурацыі javascriptEnabled:false. Паколькі ў стандартнай MongoDB файлы дадзеных не зашыфраваны, разумна запускаць MongoDB з Dedicated User, у якога ёсць поўны доступ да файлаў, з абмежаваным доступам толькі для яго і магчымасцю выкарыстоўваць уласныя сродкі кіравання доступам да файлаў аперацыйнай сістэмы.

Памылка пры распрацоўцы схемы

MongoDB не выкарыстоўвае схему. Але гэта не значыць, што схема не патрэбная. Калі вы жадаеце проста захоўваць дакументы без якой-небудзь узгодненай схемы, захоўваць іх можна хутка і проста, але выняць іх потым можа быць страшэнна складана.

Класічны артыкул «6 эмпірычных правіл для праектавання схем MongoDB» варта таго, каб яе прачытаць, а такія функцыі, як Schema Explorer у іншым інструменце Studio 3T, варта выкарыстоўваць для рэгулярных праверак схем.

Не забудзьцеся аб парадку сартавання

Забыўшыся пра парадак сартавання можна мацней за ўсё расчаравацца і страціць больш часу, чым пры выкарыстанні любой іншай няправільнай канфігурацыі. Па змаўчанні MongoBD выкарыстоўвае бінарнае сартаванне. Але наўрад ці яна будзе камусьці карысная. Адчувальныя да рэгістра, націску, бінарныя сартаванні лічыліся цікаўнымі анахранізмамі нараўне з каралямі, кафтанамі і вусамі, якія завіваліся яшчэ ў 80-х гадах мінулага стагоддзя. Цяпер жа іх выкарыстанне недаравальна. У рэальным жыцці матацыкл гэта тое ж самае, што і Матацыкл . А "Брытанія" і "брытанія" - адно і тое ж месца. Радковая літара - гэта проста вялікі эквівалент вялікай літары. І не прымушайце мяне казаць аб сартаванні дыякрытычных знакаў. Пры стварэнні базы дадзеных у MongoDB выкарыстоўвайце параметры сартавання без уліку націску і рэгістра, якія адпавядаюць мове і культуры карыстальнікаў сістэмы. Дык вы значна спросціце пошук па радковых дадзеных.

Стварэнне калекцый з вялікімі дакументамі

MongoDB рада размясціць вялікія дакументы памерам да 16 МБ у калекцыях, а GridFS прызначана для вялікіх дакументаў памерам больш за 16 МБ. Але толькі таму, што вялікія дакументы тамака можна размясціць, захоўваць іх тамака не лепшая ідэя. Лепш за ўсё MongoDB будзе працаваць, калі вы будзеце захоўваць асобныя дакументы памерам у некалькі кілабайт, разглядаючы іх больш, як радкі ў шырокай SQL-табліцы. Вялікія дакументы будуць крыніцай праблем з прадукцыйнасцю.

Стварэнне дакументаў з вялікімі масівамі

Дакументы могуць змяшчаць масівы. Лепш за ўсё, калі колькасць элементаў у масіве далёкая ад чатырохзначнага ліку. Калі элементы да масіва дадаюцца часта, ён перарасце які змяшчае яго дакумент, і яго трэба будзе перамясціць, значыць, трэба будзе абнавіць і індэксы. Пры паўторнай індэксацыі дакумента з вялікім масівам, індэксы часта будуць перазапісвацца, паколькі пад кожны элемент існуе запіс, якая захоўвае яго індэкс. Такая пераіндэксацыя таксама адбываецца, калі дакумент устаўляецца ці выдаляецца.

У MongoDB ёсць так званы "каэфіцыент запаўнення", які дае прастору для росту дакументаў, каб звесці гэтую праблему да мінімуму.
Вы можаце падумаць, што абыйсціся можна без індэксацыі масіваў. Нажаль, з-за адсутнасці азначнікаў у вас могуць з'явіцца іншыя праблемы. Паколькі дакументы праглядаюцца ад пачатку да канца, пошук элементаў у канцы масіва будзе займаць больш часу, ды і большасць аперацый, злучаных з такім дакументам, будуць павольнымі.

Не забудзьцеся, што парадак стадый у агрэгацыі мае значэнне

У сістэме базы дадзеных з аптымізатарам запытаў, запыты, якія вы пішаце, з'яўляюцца тлумачэннямі таго, што вы хочаце атрымаць, а не таго, як гэта атрымаць. Працуе такі механізм па аналогіі з замовай у рэстаране: звычайна вы проста заказваеце страву, а не даяце падрабязныя інструкцыі кухару.

У MongoDB вы інструктуеце кухары. Напрыклад, трэба пераканацца, што дадзеныя праходзяць праз reduce як мага раней у пайплайне з дапамогай $match и $project, а сартаванне адбываецца толькі пасля reduce, і што пошук адбываецца роўна ў тым парадку, у якім вам трэба. Наяўнасць аптымізатара запытаў, які пазбаўляе ад лішняй працы, аптымальна парадкуе этапы і выбірае тып злучэння, можа вас распесціць. У MongoDB у вас з'яўляецца больш кантролю коштам зручнасці.

Такія інструменты як Studio 3T спросцяць пабудову запытаў агрэгацыі ў MongoDB. Функцыя Aggregation Editor дазволіць вам прымяняць аператары пайплайна па адным этапе за раз, а таксама правяраць ўваходныя і выходныя дадзеныя на кожным этапе для спрашчэння дэбага.

Выкарыстанне хуткага запісу

Ніколі не ўстанаўлівайце ў MongoDB параметры запісу з высокай хуткасцю, але нізкай надзейнасцю. Гэты рэжым "file-and-forget" здаецца хуткім, паколькі каманда вяртаецца да таго, як ажыццяўляецца запіс. Калі сістэма ўпадзе да таго, як дадзеныя будуць запісаныя на дыск, яны згубяцца і апынуцца ў няўзгодненым стане. На шчасце, у 64-бітным MongoDB уключана часопісаванне.

Рухавікі для захоўвання MMAPv1 і WiredTiger выкарыстоўваюць лагіраванне для прадухілення гэтага, хоць WiredTiger можа аднавіцца да апошняй узгодненай кантрольнай кропкі, калі часопісаванне адключана.

Журналіраванне гарантуе, што база даных знаходзіцца ва ўзгодненым стане пасля аднаўлення і захоўвае ўсе даныя да моманту запісу ў часопісе. Перыядычнасць запісаў наладжваецца з дапамогай параметра commitIntervalMs.

Каб быць упэўненым у запісах, пераканайцеся, што ў файле канфігурацыі часопісаванне ўключана (storage.journal.enabled), а перыядычнасць запісаў адпавядае таму аб'ёму інфармацыі, які вы можаце дазволіць сабе страціць.

Сартаванне без індэкса

Пры пошуку і агрэгаванні часта ўзнікае неабходнасць у сартаванні дадзеных. Будзем спадзявацца, што гэта робіцца на адным з заключных этапаў, пасля фільтрацыі выніку з мэтай памяншэння аб'ёму сартаваных дадзеных. І нават у такім выпадку для сартавання вам спатрэбіцца індэкс. Можна скарыстацца адзінкавым ці складовым азначнікам.

Калі падыходнага азначніка няма, MongoDB абыйдзецца без яго. Існуе абмежаванне памяці ў 32 Мб на агульны памер усіх дакументаў у аперацыі сартавання, і калі MongoDB дасягне гэтай мяжы, то яна альбо выдасць памылку, альбо верне пусты набор запісаў.

Пошук без падтрымкі індэксаў

Пошукавыя запыты выконваюць функцыю аналагічную аперацыі JOIN у SQL. Для лепшай працы ім патрэбен азначнік ключа, выкарыстоўванага ў якасці вонкавага ключа. Гэта невідавочна, паколькі выкарыстанне не адлюстравана ў explain(). Такія індэксы з'яўляюцца дадаткам да індэкса, запісанага ў explain(), які ў сваю чаргу выкарыстоўваецца аператарамі пайплайну $match и $sort, калі тыя сустракаюцца ў пачатку пайплайну. Індэксы зараз могуць ахопліваць любую стадыю пайплайна агрэгацыі.

Адмова ад выкарыстання мультыабнаўленняў

метад db.collection.update() выкарыстоўваецца для змены часткі існуючага дакумента ці цэлага дакумента, аж да поўнай замены ў залежнасці ад зададзенага вамі параметру update. Не так відавочна, што ён не апрацуе ўсе дакументы ў калекцыі, пакуль вы не ўсталюеце параметр multi для абнаўлення ўсіх дакументаў, якія адпавядаюць крытэрам запыту.

Не забудзьцеся аб важнасці парадку ключоў у хэш-табліцы

У JSON аб'ект складаецца з неўпарадкаванай калекцыі памерам нуль або больш пар імя/значэнне, дзе імя - гэта радок, а значэнне - гэта радок, лік, лагічнае значэнне, нуль, аб'ект або масіў.

Нажаль, BSON надае вялікае значэнне парадку пры пошуку. У MongoDB парадак ключоў усярэдзіне ўбудаваных аб'ектаў мае значэнне, Г.зн. { firstname: "Phil", surname: "factor" } - гэта не тое ж самае, што { { surname: "factor", firstname: "Phil" }. Гэта значыць, вы павінны захоўваць у дакументах парадак пар імя/значэнне, калі жадаеце быць упэўненыя ў тым, што знойдзеце іх.

Не блытайце "Нулявы" и "undefined"

Значэнне "undefined" ніколі не было дапушчальным у JSON, згодна афіцыйнаму стандарту JSON (ECMA-404, Раздзел 5), нягледзячы на ​​тое, што яно выкарыстоўваецца ў JavaScript. Больш за тое, для BSON яно састарэла і пераўтвараецца ў $null, Што не заўсёды зяўляецца добрым рашэннем. Пазбягайце выкарыстання "undefined" у MongoDB.

Выкарыстанне $limit() без $sort()

Вельмі часта, калі вы вядзеце распрацоўку ў MongoDB, карысна проста ўбачыць узор выніку, які вернецца з запыту ці агрэгацыі. Для гэтай задачы вам спатрэбіцца $limit(), але яго ніколі не павінна быць у фінальнай версіі кода, калі толькі перад ім вы не карыстаецеся $sort. Гэтая механіка патрэбна, паколькі інакш вы не можаце гарантаваць парадак выніку, і не зможаце надзейна праглядаць дадзеныя. У верхняй частцы выніку вы будзеце атрымліваць розныя запісы ў залежнасці ад сартавання. Для надзейнай працы запыты і агрэгацыі павінны быць дэтэрмінаваны, гэта значыць выдаваць аднолькавыя вынікі пры кожным выкананні. Код, у якім ёсць $limit(), але не $sort, не будзе з'яўляцца дэтэрмінаваным і пасля можа выклікаць памылкі, якія будзе цяжка адсачыць.

Заключэнне

Адзіны спосаб расчаравацца ў MongoDB - гэта параўноўваць яе непасрэдна з іншым тыпам баз дадзеных, такім як СКБД, або прыйсці да яе выкарыстання, зыходзячы з нейкіх пэўных чаканняў. Гэта ўсё роўна што параўноўваць апельсін з відэльцам. Сістэмы баз дадзеных перасьледуюць пэўныя мэты. Лепш за ўсё проста зразумець і ацаніць для сябе гэтыя адрозненні. Было б сорамна ціснуць на распрацоўшчыкаў MongoDB з-за шляху, які прымусіў іх ісці па шляху СКБД. Мне жадаецца бачыць новыя і цікавыя спосабы рашэння старых праблем, такіх як забеспячэнне цэласнасці дадзеных і стварэнне сістэм дадзеных, устойлівых да збояў і нападам зламыснікаў.

Укараненне ў MongoDB у версіі 4.0 ACID transactionality – добры прыклад укаранення важных паляпшэнняў інавацыйным шляхам. Мультыдакументальныя і мультыаператарныя транзакцыі зараз атамарныя. Таксама з'явілася магчымасць рэгуляваць час, неабходны для атрымання блакіровак, і сканчаць завіслыя транзакцыі, а таксама змяняць узровень ізаляцыі.

14 рэчаў, якія я хацеў бы ведаць перад пачаткам працы з MongoDB

Чытаць яшчэ:

Крыніца: habr.com

Дадаць каментар