18. Бази данни с Mongo
Бази данни: кратка история
- Текстови файлове (като CSV)
- Key-value stores (BerkleyDB, Redis, shelve)
- Обектни бази данни
- Релационни бази данни (MySQL, SQLite, PostgreSQL, Oracle)
- Документни бази данни (MongoDB, CouchDB)
- Клиент/сървър или вградени
Видове схеми (schema)
Схема - структурата на една база данни.
Фиксирана схема
- SQL
- Силна, добре обмислена структура
- Базата гарантира валидността на данните
- Нормализация (данните не се повтарят)
- Опит, стабилност и традиции
- Но...
- Промените по схемата са тромави до невъзможни
- Денормализация
Видове схеми 2
Динамична схема
- Key-value и документни бази данни
- Структурата е по конвенция
- Бързо разработка и лесни промени
- Гъвкави типове данни
- Но...
- Няма стандарт и портабилност
- По-малко помощни технологии
- Сами гарантирате валидността на данните
- Кода ви трябва да е очаква много повече специални случаи
Защо да бягаме от релационните бази данни?
- Все пак са доказан вариант
- Показали са сериозна стабилност
- Има кой да ви пази
- Ако не ни кефи релационният модел имаме ORM
Безумно сложни са!
- Data Definition Language е сложен
- Data Modification Language е още по-сложен
- Транзакции и нива на изолоция
- Не наподобява на нищо подобно
Нормализация
- Кога искаме да нормализираме и кога - не?
- Има нормални форми, как решаваме коя да използваме!?
JOIN
- Разликата между LEFT JOIN и RIGHT JOIN
- Кога използваме едното и кога другото?
Key-value Stores
Изпълняват две операции
- get(key)
- set(key, value)
Стойностите са непрозрачни, може да се търси само по ключ.
>>> import shelve >>> s = shelve.open("mydb.db") >>> s['hello'] = True >>> s['goodbye'] = 'Bob' >>> s.close()
dbm е по-гъвкава алтернатива на shelve
Документни бази данни
- Като key-value store, но със структурирани стойности.
- Стойностите са JSON (или подобни) документи.
- Отделните полета могат да съдържат сложни обекти (няма нужда от релации).
- Може да се търси и индексира по отделни полета в документа.
- Могат да се променят отделни полета в документа.
Влиза Mongo
- Клиент/сървър документна база данни
- http://mongohq.org
- Бърза разработка
- Стабилна - ползва се в големи сайтове
- Удобен език за търсене и редактиране
- Репликация и многосървърна работа, търсене, записване на файлове, MapReduce, и т.н.
Как се казват нещата в Mongo
- Наименовани бази (пр. "myapp")
- ...съдържат наименовани колекции (пр. "users")
- ...съдържат записи с ключ и документ (пр. ключ "25")
Операции
- collection.insert(value)
- collection.find_one({conditions})
- collection.find({conditions})
- collection.update({conditions}, {changes})
- collection.save({document})
Ключове и стойности
- Стойноста на всеки Mongo запис е JSON-подобен обект
- Ключът на всеки запис е или случайно избран, или стойноста на полето _id в обекта
- Случайно избраните ключове са UUID, като 4c2209f9f3924d31102bd84a (тип: ObjectId)
ObjectId
Уникален идентификатор за всеки запис
Код
pip install pymongo
import pymongo mongo = pymongo.Connection('localhost') db = mongo['myapp'] users = db['users'] users.insert({'_id': 'bob', 'firstname': 'Bob', 'lastname': 'Red', 'phones': ['0888112233', '0899334455']}) user.find_one('_id': 'bob')
Библиотека
- Книги
- Автори
- Магазини
Ключове
Как да си изберем ID (primary key)?
- ISBN?
- Баркод?
- Заглавие?
- Използвайте поредни/случайни числа за ID, освен ако нямате много силна друга причина.
Книги
Книгата има следните полета
- title
- isbn
- authors
- publisher
- year_of_publishing
- description
- price
- qty_available
Автори
- first_name
- last_name
- bio
- books
Ъпдейти
- $inc
- $set
- $unset
- $push
- $pushAll
- $addToSet
- $each
- $pop
- $pull
- $pullAll
- $rename
- $bit
Търсения
books.find({'title': '1984'}).sort({'year_of_publishing': 1})
- Можем да избираме кои полета да получим
- Очевидно можем да укажем и кои да НЕ получим
- Можем да избираме по коя колоне ще сортираме
- От кой елемент нататък да започнем
Сложни търсения
- >, =, <, >=, <=
- $all
- $exists
- $mod
- $ne
- $in
- $nin
- $nor
- $or
- $and
- $size
- $type
Индексиране
- Концептуално подобни са с RDBMSes
- С ensureIndex() избираме кои полета да са индекси
Още въпроси?
- Пишете ни на fmi@py-bg.net
- Страница на курса: http://fmi.py-bg.net/
- Форуми на курса: http://fmi.py-bg.net/topics
- Курсът в Twitter: http://twitter.com/pyfmi
- Курсът във Facebook: http://www.facebook.com/group.php?gid=104970619536589