Документы с моделью тегов в IndexedDB - PullRequest
1 голос
/ 19 февраля 2012

У меня есть песни и теги. Тег может быть типа «место записи» или «дата последней записи».

В реляционной модели у меня была бы модель соединения, содержащая информацию song_id и tag_id. Но в БД базы документов, такой как indexeddb, я бы хранил теги и их информацию прямо в документе. Интересно, не приведет ли это в конечном итоге к загрузке БД в долгосрочной перспективе, если у меня не будет много уникальных тегов?

Если для другой песни потребуется один из тегов, которые уже используются в другой песне, у меня будет дублирующий тег.

Я, конечно, тоже мог бы пойти с хранилищем соединений, но это также включало бы ручные выборки для 2 таблиц.

У меня есть несколько вопросов к модели:

  1. Должен ли я иметь магазин песен и тегов?
  2. Как выполняется массовое обновление тегов, которые прикрепляются к каждой песне?
  3. Какие показатели мне, вероятно, понадобятся, чтобы сделать это быстро?

Мой главный аспект - поиск по значениям тегов (и фильтрация по типу).

Ответы [ 2 ]

1 голос
/ 21 сентября 2012

Ключ к хорошему использованию IDB и других хранилищ NoSQL заключается не в том, чтобы быть захваченным идентификаторами соединений, а просто в попытках сделать каждое хранилище объектов полезным для себя. (И хорошо использовать индексы!) Помните, что именно так работают базы данных SQL-ish, но это позволяет вам делать специализированные объединения , когда вам это нужно , а не в общем случае.

Массовые обновления - это более сложная задача, но речь идет скорее об оптимизации для наиболее распространенного случая (отображение поиска песен / тегов), чем о более редких вещах (массовое изменение имен тегов)

Самая базовая схема, на которую вы смотрите, - это хранить песни как что-то вроде:

{ name: "Name of Song"
  id: <song id>
  tags: ["tag1", "tag2", "tag3"] }

А теги можно просто идентифицировать по их имени:

{ name: "tagname"
  description: "Some tag description or whatever" }

Сначала создайте свою песню objectStore:

var songs = db.createObjectStore("songs", "id");

Затем создайте индекс multiEntry:

songs.createIndex("tags", "tags", {multiEntry: true});

Затем создайте тег objectStore:

var tags = db.createObjectStore("tags", "name");

Теперь вы можете выполнять соединения самостоятельно, если вам это действительно нужно, но иногда это просто некоторые включения.

var trans = db.transaction(["songs", "tags"]);

var songTags = [];
trans.objectStore("songs").get("songid").onsuccess = function(e) {
    var song = e.target.result;
    for (var i = 0; i < song.tags.length; i++) {
        trans.objectStore("tags").get(song.tags[i]).onsuccess = function(e) {
            var tag = e.target.result;
            songTags.push(tag);
        }
    }
}
trans.oncomplete = function(e) {
     showSongTags(songTags);
}

Благодаря индексу 'tags' в песнях обратное тоже довольно просто. Обратите внимание, что мы используем имена тегов напрямую, а не возимся с каким-то промежуточным числовым тегом_ид.

var trans = db.transaction(["songs", "tags"]);

var songs = [];
trans.objectStore("songs").index("tags").openCursor("tag1").onsuccess = function(e) {
    var cursor = e.target.result;
    if (!cursor) return;

    cursor.continue();
    songs.push(cursor.value);
}
trans.oncomplete = function(e) {
     showSongs(songs);
}
0 голосов
/ 23 марта 2012

Вы в основном сталкиваетесь с той же проблемой, с которой сталкиваются люди, когда им приходится выбирать между реляционной базой данных, такой как MySQL, и документно-ориентированной, такой как MongoDB. Дублирование данных - не говоря уже о самих ключах - занимает место, и определенно больше «третьей формы» - хранить одну копию и использовать вместо нее внешние ключи.

Тем не менее, я прошел через обе стороны в моей работе IndexedDB. Вера в то же, что вы делаете - в отношении эффективности хранения - должна быть сопоставлена ​​с фактическим доступом к данным. Если вы хотите создать схему, подобную внешнему ключу, в IndexedDB, это обязательно требует более двух хранилищ объектов, например, хранящихся в виде двух отдельных файлов в базовой файловой системе. Это означает, что для каждого запроса, для которого вы хотите получить данные внешнего ключа (здесь, теги), у вас должно быть как минимум два обращения к хранилищу объектов, возможно, две транзакции и, я предполагаю, дополнительные накладные расходы ввода-вывода и тому подобное, связанные с ними.

Я бы пошел с подходом, ориентированным на документы, и попытался бы сделать хранилище менее серьезным с помощью таких хитростей, как сокращение (например, «n» вместо «name»).

...