Чи правильний вибір MongoDB в моєму випадку? [зачинено]


9

Я збираюся побудувати свій перший реальний проект у Rails, який складається з веб-додатку, який складається з 3 основних частин:

  • Статична частина, де не використовується база даних
  • Частина реєстрації користувача, яка потребує бази даних, і я можу використовувати MySQL, оскільки кожен рядок користувача матиме однакові поля
  • "Додаток", де користувачі зможуть створювати, упорядковувати, редагувати ... елементи у колекціях та ділитися ними з іншими користувачами

Буде кілька типів предметів, і кожен з них матиме різні варіанти, наприклад, у мене можуть бути "відео" елементи з такими параметрами:

  • ід
  • ідентифікатор користувача
  • collection_id
  • назва
  • платформа (якщо вбудована)
  • URL (якщо він вбудований)
  • ім'я файлу (якщо він розміщений у моєму додатку)
  • розмір файлу (ідентифікатор, розміщений у моїй програмі)

та "карта" елементів:

  • ід
  • ідентифікатор користувача
  • collection_id
  • назва
  • платформа (google maps, bing maps ...)
  • Розташування
  • URL
  • розмір карти

Як ви можете, тоді як для користувачів я можу використовувати MySQL для елементів, гнучкість MongoDB може бути корисною, оскільки для кожного елемента можуть знадобитися різні параметри, аніж іншого.

До цих пір я завжди використовував PHP та MySQL (завжди на спільному хостингу для невеликих проектів), і масштабованість - це абсолютно нове слово для мене.

У мене є час вчитися, але я хотів би мати можливість зробити щось конкретне за щось на зразок 1 місяця.

Я багато читав про MongoDB і NoSQL vs RDMS і MySQL, і після його спробу я мушу сказати, що мені подобається, як працює MongoDB: немає таблиць, жодних рядків та його документів JSON так:

  • Що в моїй ситуації, що ти би ратував? чому?
  • З приводу масштабованості можуть виникнути проблеми з MongoDB? якщо так, коли (з точки зору розміру БД) і чи можуть ці проблеми значно сповільнити додаток?

Редагувати: як програма працюватиме

Оскільки багато хто запитує, як би я хотів, щоб програма працювала:

  1. Користувач підписується
  2. Він увійшов до системи
  3. Він створив свою першу колекцію iside, яку він може створити нескінченно
  4. Елементи мають різний тип, і для кожного типу потрібні різні дані для збереження в базі даних, а тип елементів може бути доданий або змінений

Користувачі можуть створювати інші колекції та предмети всередині нього.

Таким чином, у нас є CRUD для колекцій та предметів всередині них, і кожна колекція / елемент передається конкретному користувачеві

Основна проблема MySQL полягає в тому, що вона не має гнучкої схеми, є спосіб вирішити це (вирішення?)?

Думаючи про NoSQL, у мене є єдиний сумнів щодо приєднання, наприклад, з урахуванням певного вибору, я хочу отримати дані, пов'язані з Користувачем, у колекції поле id = user_id

EDIT: Ідея продовжувати використовувати MySQL

Створіть поле в таблиці "елементи" з необов'язковими налаштуваннями, кожне налаштування поділене на | або інший символ.

Тоді я десь збережу структуру кожного елемента, необов'язкові параметри, наприклад, типу елемента "нотатки" потрібні два необов'язкові налаштування "колір" і "дивне_настройка", коли я отримаю дані з MySQL, я розділю поле для необов'язкових параметрів на масив знаючи, що перший елемент у масиві призначений для "кольору" тощо.

Як ти гадаєш? є проблеми з цим рішенням? у вас є інші ідеї?


4
Питання Matteo щодо технологічних рекомендацій поза темою, якщо ви не представите нам певну проблему, яку ви намагаєтеся вирішити. Вам потрібно буде надати нам трохи більше інформації про ваш проект та про те, чому ви вважаєте, що вам потрібно використовувати будь-яку іншу базу даних, ніж MySQL (це та, з якою ви знайомі). Наприклад: Чи є якісь проблеми щодо масштабованості та скільки часу у вас є на вивчення нових технологій. Подумайте переглянути своє запитання, і якщо це зробити, позначте його на модераторну увагу, щоб ми могли переглянути ваші зміни.
янніс

Відповіді:


10

Ми можемо не допомогти вам, поки ви не скажете нам, що ви маєте намір робити з додатком. Реляційні бази даних корисні для певних речей, а бази даних NoSQL - корисні для інших.

Як хтось колись сказав мені сюди, так:

реляційна частина реляційної БД значно оптимізована, ніж деякі інші частини

Це означає, що ви можете використовувати реляційну базу даних також, якщо це, здається, відповідає вашим випадкам використання. Не просто випереджайте MongoDB через його гнучкість / масштабованість. Це перший рядок про MongoDB у Вікіпедії:

MongoDB (від "humongous") - це система баз даних NoSQL, орієнтована на відкритий код.

Ви дійсно маєте намір використовувати орієнтований на документ БД? Якщо у ваших випадках використання є деяка графічність, то ви цілком можете звернутися до бази даних графіків, наприклад Neo4j. Або ви можете дуже добре використовувати найкраще як SQL, так і NoSQL разом, як це роблять деякі люди.

До речі, я також роблю проект, в якому використовую найкращі частини як SQL, так і NoSQL.

EDIT: Я ще раз кажу:

Перегляньте розділ Neo4j vs Hadoop у цій статті. Він говорить:

В принципі, Hadoop та інші сховища ключових цінностей в основному стосуються відносно рівних структур даних . Тобто вони надзвичайно швидкі та масштабовані щодо пошуку простих об'єктів, таких як значення, документи чи навіть предмети.

Посилаючись на ту саму статтю, чи справді вам потрібна рівна структура даних, для якої ви збираєтеся MongoDB? Це врешті-решт залежить від ваших детальних випадків використання, способів виконання кроків 3 та 4.

Крім того, ви можете звернутися до цих питань:

/programming/2124274/mongodb-what-to-know-before-using

/programming/1476295/when-to-use-mongodb-or-other-document-oriented-database-systems

( Напевно ознайомтеся з найвищою / вибраною відповіддю на друге питання. Ви перебуваєте в тій дилемі, що це може просто вирішити. )

Я думаю, що в цих питаннях є вся інформація, яку ви хотіли знати. Зрештою, саме вам доведеться вирішити, чи це MongoDb чи щось інше, ми можемо просто рекомендувати. Єдині люди, які знають ваші випадки детального використання - це ви та ваша команда.

РЕДАКТУЙТЕ ПРОТИ (для частини MySQL): Як я зрозумів, ви плануєте зберігати щось у db та розділяти їх через роздільник. Тут представлені дві проблеми:

  1. Вам потрібно додатково обробити будь-який вхід, який матиме роздільник.
  2. Частина реляційного зберігання реляційної бази даних значно оптимізована, ніж частина, що відповідає рядку. Я б не пішов на схему, де мені потрібно виконати відповідність рядків у базі даних, щоб отримати певний результат. Знову наголошую:

    реляційна частина реляційної БД значно оптимізована, ніж деякі інші частини (наприклад, відповідність рядків)

  3. Не використовуйте багатозначні атрибути. Люди взагалі бояться їх.

в основному я збирався використовувати MongoDB для своєї гнучкої схеми, але у мене є певні сумніви, оскільки він не має приєднатися. У будь-якому додатку у мене буде база даних dtabase для користувачів, а потім базовий креуд, де кожен елемент асоціюється з користувачем та колекцією елементів
Matteo Pagliazzi

Вам не потрібно буде приєднуватися до mongo, але вам потрібно буде спланувати свою схему. Подумайте про терміни об'єктів замість таблиць, якщо ви використовуєте mongo. Тоді подумайте, як ви отримаєте доступ до своїх об’єктів.
ltfishie

8

Я бачу це питання багато. Це завжди, здається, вважається як / або. MongoDB - чудовий новий інструмент. Це також іноді здається блискучим інструментом для всього, і це може бути поганим вибором на моєму досвіді.

Я думаю, що найкраща комбінація, безумовно, БУТИ, і я хотів би похвалити вас за ваш підхід до використання mylsql для деяких частин, таких як користувачі, але використовувати MongoDB для інших частин, оскільки я вважаю, що автентифікація та авторизація найкраще проводити за допомогою mySQL і є тонна прикладів та модулів, які роблять це справді добре.

Для частини "великої кількості елементів" саме тут ви хочете розглянути можливість використання mongoDB, якщо ваш об'єм великий, та / або в основному він читає та / або це неструктуровані дані.

Я б радив не базувати своє рішення на гнучкості схеми Монго. SQL та sql-схеми виникли з необхідності мати структуровані дані та вміти виконувати обчислення та перетворення, які можливі лише за такої структури. Я дізнався це за 5 років роботи в сховищі даних. Я хотів би лише звернутися до MongoBD щодо питання про продуктивність. Якщо ви або очікуєте великого обсягу користувачів і запитів, скажімо, 100 000 користувачів і 20 запитів в секунду, я б використовував mongoDB, інакше я б спробував залишитися з sql. У багатьох випадках я використовував би mySQL для низького обсягу, а потім, як об'єм, дохід та інфраструктура його підтримують, переходимо на Oracle, перш ніж змішувати в mongoDB. Я погоджуюся, що вам не слід намагатися вирішувати проблеми з обсягом, перш ніж ви їх відчуєте, однак якщо у вас є чітке уявлення про те, куди ви прямуєте і не робите ' не хочу переписувати речі на півшляху, має сенс правильно вибрати технології на початку. Просто пам’ятайте, що якщо у вас дійсно такий великий обсяг, існує величезна кількість варіантів та технологій на всіх рівнях стеку, які ви хочете використовувати.

Існує недолік слабко структурованих даних. Я тут використовую аналогію стоянки. ніякі розділові лінії не чудово підходять для перших трьох автомобілів, які в’їжджають, але в міру того, як все більше автомобілів заходить, починається багато дезорганізуючих і намагаються припаркуватися або легко порахувати машини та тримати смуги вільними стає кошмаром. Організація цього вимагає роботи вперед - маркування ліній і роздільників, потоків руху тощо, але це окупається. Іноді речі змінюються звичайно (автомобілів стає більше), і вам доведеться зробити деякі зміни - перефарбувати лінії. Плюс просто стандартний час простою для щорічного перепланування та обслуговування.

Аспект дизайну схеми, ймовірно, буде найбільшою перешкодою для традиційних користувачів mysql. Я думаю, що в цьому допомагає сторінка MongoDb щодо дизайну схем . Моє остаточне значення полягає в тому, що кожна технологія, яку ви додаєте в суміш, додає складності. Часто існує величезна кількість прихильників будь-якого твору, який скаже, що ви "маєте" його використовувати, але я виявив, що дійсно великим фактором є саме стільки штук. Це передбачає більше можливих моментів невдач і, головне, більше бази знань, необхідних для того, щоб хто-небудь інший повинен знати, щоб працювати над цим.

Фік Рік Обсорн має досить дивовижну діаграму порівняння, яка цілком унікальна!


це мій перший справжній проект на рейках: це хобі, і на даний момент я не знаю, чи це буде успіх, чи провал, моя перша мета тут - ознайомитися з рейками, щоб я не міг говорити про рух. Читання не будуть первинними, у мене також буде багато нових даних та оновлених ...
Маттео Пальяццац

1
Хороша річ у mongodb - це відсутність фіксованої схеми, тому для хобі-проекту менше роботи з налаштування. Схема може розвиватися з часом, і вам не потрібно робити зайвий крок оновлення таблиць SQL.
Кевін

не впевнений у моїх -1 чи чому 0 поганих порад чи незгодних?
Майкл Дюррант

У будь-якому випадку, якщо це ваш перший проект на рейках, я би дотримувався mySQL. Існує багато, щоб навчитися на рейках, набагато більше, ніж один місяць варто, як тільки ви почнете відтягувати штори.
Майкл Дюррант

@michael дивіться моє останнє оновлення
Matteo Pagliazzi

3

Я бачу тут багато вагомих аргументів для NoSQL проти MySQL. Хоча одне відсутнє посилання стосується масштабу: Якщо ви хочете дійсно масштабувати і хочете це зробити з базою даних в будинку, вам знадобиться багато знань про бази даних. Надто багато страшилок там, де люди не змогли втілити систему, яка масштабуватиметься нескінченно.

Якщо ви дійсно вирішите піти по маршруту NoSQL (і готові взяти на себе витрати, які пов'язані з ним - як не приєднуйтесь), то врахуйте AWS DynamoDB (http://aws.amazon.com/dynamodb/). Тут ви можете забути про всю базу даних, яка масштабує її частину, і сконцентруватися на вашому застосуванні. Удачі.

Відмова: Я розробник команди AWS DynamoDB, але я справді вірю в наш продукт. Спробуйте це :)


1

Отже, ваш дизайн отримує для збереження у вашій базі даних два різних об'єкти:

  • Об'єкт користувача (у якому завжди є поля).
  • Об'єкти програм (які можуть мати різні поля). Додаток належить лише одному користувачеві.

Колекція могла чи ні я зроблена як інший об’єкт, як це лише тег для групування різних програм. На думку аргументів, скажімо, що колекцій немає, а користувачі мають лише список програм.

Хоча я думаю, що це можливо для MySQL, у MongoDB ви будете мати більшу гнучкість у структурі об’єктів додатків, і, ймовірно, це відобразить більш природно ваше представлення в базі даних, що спростить код.

У MySQL у вас будуть проблеми з різними форматами для різних додатків, але це можливо. Деякі ідеї:

  • Ви можете створити проміжну таблицю з усією загальною інформацією між усіма об'єктами (id, user_id, title тощо), а потім тип, і ви можете шукати її в іншій таблиці, тільки для неформальних полів для цього формату (наприклад, ім'я файлу та розмір файлу для файлів). Вам потрібно буде створити іншу таблицю для кожного іншого формату. Якщо обидві таблиці індексуються app_id (Первинний ключ), це буде досить швидко, оскільки доступ до таблиці індексованим значенням швидкий.
  • Ви можете кодувати дані в якомусь форматі та зберігати стандартизовані. Наприклад, кодуйте незвичайні дані в JSON як рядок і зберігайте їх у полі VARCHAR. Будьте уважні до розміру цього поля, щоб у вас не вистачало місця. Формат може бути складним (JSON) або простим (просто значення, розділені комами)
  • Ви можете створити різні "загальні" поля, щось на зразок int1, int2, str1, str2, і визначити, що str1 для типу програми є "file_name", тоді як для іншого типу може бути "location".

На MongoDB це може бути так само просто, як просто використання двох колекцій MongoDB, одна для користувачів та ще одна для додатків. Якщо припустити, що це обмеження (це не так, як ви описали, а просто для того, щоб сказати), ви навіть можете зберігати програми всередині об’єкта користувача, як список. Зберігання та отримання даних є більш природним, оскільки ви можете зберігати будь-який тип об’єктів, незалежно від того, які поля є. Ви можете здійснювати пошук по user_id, щоб отримати всі програми, що належать користувачеві. У MongoDB у будь-якому випадку ви втрачаєте можливість робити запити на приєднання, але в цьому випадку я думаю, що основними запитами буде пошук користувача та завантаження програм, пов’язаних із користувачем. Якщо ви плануєте зробити багато речей, як-от "дайте мені користувачам, у яких більше двох колекцій із трьома програмами чи менше на кожного", вам доведеться генерувати це не як запит на приєднання, але як процес у коді, він буде менш природним, ніж у реляційній базі даних, і може зайняти більше часу на обробку. Якщо ви хочете шукати параметри (наприклад, дайте мені всі програми, що належать певному користувачеві; дайте мені всі програми типу X), це досить просто в MongoDB і не потрібно використовувати приєднання.

Я не впевнений у підтримці MongoDB на Rails. Я використовую його в Python та JavaScript.

EDIT: Додано коментар про час доступу до двох таблиць та іншої опції MySQL


мені не подобається другий варіант використання MySQL для зберігання необов’язкових параметрів, тому що я думаю, що він може завантажувати кожен ряд з великою кількістю непотрібних байтів ... для другого: це дуже сповільнить моє додаток, щоб завантажити два ряди з двох різних таблиць, щоб завантажити один елемент?
Маттео Пальяцці

перегляньте моє останнє оновлення
Маттео Пальяцці

Щодо вашого питання щодо швидкості, воно не повинно бути набагато повільніше (ви отримуєте доступ до нього через індексовану унікальну величину). Я також відредагував свою відповідь, оскільки остання відредагована пропозиція схожа на першу ідею, і додав інший варіант.
Хелбен

1

Я б сказав, використовуйте технологію, яку ви найкраще знаєте, особливо якщо це справжній проект і ви хочете швидко його витіснити. Використання MySQL та Mongo принесе свої переваги та головні болі. Працюючи з обома, я також додам, що перейти з MySQL до Монго не дуже складно, якщо ви будете слідувати хорошим принципам дизайну.

Зважаючи на це, одна з вагомих причин зв’язатися з MongoDB у вашому випадку - це ваші дані. Як ви вже згадували, для ваших колекцій у вас буде кілька різних типів запису: карта, відео тощо. Якщо ви реалізували це за допомогою RDBMS, у вас є три підходи:

  • таблиця на тип: кожна таблиця містить стовпці, характерні для кожного типу об’єктів

    Недоліки : N запитів для пошуку всіх типів даних.

    Переваги : хороший дизайн OO, легко у обслуговуванні

  • одна таблиця: одна величезна таблиця, що містить усі можливі атрибути для всіх типів, при цьому більшість з них є нульовими для будь-якого конкретного запису

    Недоліки : зміна будь-якого об'єкта потребує змінити таблицю, болісна, коли таблиця стане великою. Складно підтримувати.

    Переваги : Простота у виконанні.

  • основна таблиця з метаданими: у вас є одна таблиця з атрибутами core, скажімо, заголовком, датами та таблиця метаданих з парами ключ-значення для додаткових атрибутів

    Недоліки : два запити, щоб отримати всі дані для одного об’єкта.

    Переваги : надзвичайно гнучка, не дуже складна у виконанні.

Раніше я використовував кожен із цих підходів, і можу сказати, що жоден не так природно працює з Монго. Можливо, ваші дані будуть виглядати приблизно так:

{_id:"collection1",
 name:"My first Collection",
 owner: "user123243342",
 entries: [
    {type:"video",
     url: "http://www.youtube.com/234324",
     tags: ["roadtrip", "fun", "camera"]
     },
    {type:"map",
     coordinates: [LOC: [38, –102], LOC: [43, –33], LOC: [228, –102]],
     description: "Road trip to nowhere",
 ]
}

Але вам не доведеться турбуватися про схему дизайну, оскільки об’єкти вашого домену можуть зберігатися безпосередньо як такі. MongoDB по суті - це ваш магазин об'єктів, до якого ви можете запитувати.

Помітив, що я покинув будь-які дискусії щодо порівняння продуктивності між MySql та Mongodb. Хоча ви завжди повинні мати на увазі ефективність роботи, ви не зможете ефективно приймати рішення, якщо ви не знаєте схему доступу до даних. Будь-який хороший проект, ймовірно, пройде через кілька ітерацій рефакторингу в міру його зростання та появи нових викликів. Не переживайте про продуктивність достроково і виберіть інструмент, який ви найкраще знаєте, і починайте кодувати.

Редагувати

Щоб відповісти на ваше конкретне запитання щодо використання MySQL та збереження атрибутів у тому ж полі, використовуючи "|". Не робіть цього. Такий підхід дасть вам більше проблем, ніж вирішує. Перш за все, ви не зможете запитувати окремі атрибути за допомогою MySql. По-друге, це додає занадто великої складності вашому шару доступу до даних. Використовуйте замість цього тип типу на таблицю або підхід мета-даних. Якщо ви працювали з WordPress раніше, він використовує метадані підхід:

  • таблиця користувача + usemeta для користувача
  • таблиця пошти + постмета таблиця пост

Це робить структуру даних надзвичайно гнучкою і все ще може мати запит з розумною швидкістю.


мені не подобається параметр метаданих ... але я розмірковую над єдиною таблицею з полями, які залишилися нульовими, якщо вони не використовуються
Matteo Pagliazzi

Підхід до єдиного столу - це, мабуть, найгірше. Хоча ви можете робити все в одному запиті, будь-яка зміна будь-якого одного типу даних вимагатиме зміни таблиці. І це біль у mysql, коли ваш стіл стає великим.
ltfishie

0

Стаття нижче дає хороші результати порівняння MySQL та MongoDB з точки зору вибору, отримання та вставки, враховуючи кількість даних у базі даних та кількість отриманих даних. Результати показують велику ефективність для MongoDB щодо "вставок", але в інших випадках MySQL виграє. Дивись нижче:

http://www.moredevs.ro/mysql-vs-mongodb-performance-benchmark/

У мене був досвід використання MongoDB, і я думаю, що це було гарне рішення. Я використовував це, щоб вставляти тисячі колекцій щодня. У поєднанні з рішенням Solr (кеш-рішення, оновлюється один раз на день) я можу отримати дані MongoDB за ідентифікатором колекції, коли це потрібно, тому мені не потрібно вибирати під час руху. Отже, враховуючи, що вам доведеться мати багато вставок і не потрібно дбати про вибір та отримання, MongoDB може бути чудовою ідеєю, це буде залежати від кожного конкретного випадку та зробити хороший аналіз.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.