Проектирование баз данных для меток

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

165
задан Sampson 19 November 2011 в 03:46
поделиться

10 ответов

О Выполнении операции "И": Это кажется на поиск "реляционного подразделения" операция. Эта статья касается реляционного подразделения кратким и все же comprehendible способом.

О производительности: основанный на битовом массиве подход интуитивно кажется, что хорошо подойдет ситуации. Однако я не убежден, что это - хорошая идея реализовать растровую индексацию "вручную", как digiguru предлагает: Это походит на сложную ситуацию каждый раз, когда новые теги добавляются (?), но некоторые системы управления базами данных (включая Oracle) растровые индексы предложения, которые могут так или иначе быть полезными, потому что встроенная система индексации покончила с потенциальной сложностью ведения индексов; дополнительно, DBMS, предлагающий растровые индексы, должен быть в состоянии рассмотреть их в надлежащем когда при выполнении плана запросов.

21
ответ дан Troels Arvin 23 November 2019 в 21:10
поделиться

Вот хорошая статья о метках Схем базы данных:

http://howto.philippkeller.com/2005/04/24/Tags-Database-schemas/

наряду с тестами производительности:

http://howto.philippkeller.com/2005/06/19/Tagsystems-performance-tests/

Примечание, что заключения там очень характерны для MySQL, который (по крайней мере, в 2005 в то время, когда был записан) имел очень плохие характеристики полнотекстового индексирования.

74
ответ дан hansaplast 23 November 2019 в 21:10
поделиться

Я не вижу проблемы с простым решением: Таблица для объектов, таблица для тегов, кросс-таблица для "меток"

Индексы на кросс-таблице должны быть достаточной оптимизацией. Выбор соответствующих объектов был бы

SELECT * FROM items WHERE id IN  
    (SELECT DISTINCT item_id FROM item_tag WHERE  
    tag_id = tag1 OR tag_id = tag2 OR ...)  

, И метки будут

SELECT * FROM items WHERE  
    EXISTS (SELECT 1 FROM item_tag WHERE id = item_id AND tag_id = tag1)  
    AND EXISTS (SELECT 1 FROM item_tag WHERE id = item_id AND tag_id = tag2)  
    AND ...

, который является по общему признанию, не настолько эффективен для большого количества сравнения тегов. Если необходимо поддержать количество тега в памяти, Вы могли бы сделать запрос для запуска с тегов, которые являются не часто, таким образом, И последовательность был бы оценен более быстрый. В зависимости от ожидаемого количества тегов, которые будут согласованы против и предвкушение соответствия любому синглу их, это могло быть решением для OK, если необходимо соответствовать 20 тегам и ожидать, что некоторый случайный объект будет соответствовать 15 из них, тогда это все еще было бы тяжело на базе данных.

13
ответ дан Slartibartfast 23 November 2019 в 21:10
поделиться

Я просто хотел выделить это статья, что @Jeff ссылки Atwood на ( http://howto.philippkeller.com/2005/04/24/Tags-Database-schemas/ ) очень полны (Она обсуждает достоинства 3 различных подходов схемы), и имеет хорошее решение для И запросы, которые будут обычно работать лучше, чем, что было упомянуто здесь до сих пор (т.е. она не использует связанный подзапрос на каждый термин). Также много хорошего материала в комментариях.

пикосекунда - подход, о котором все говорят здесь, упоминается как решение "Toxi" в статье.

13
ответ дан Himanshu 23 November 2019 в 21:10
поделиться

Самый легкий метод должен создать теги таблица.
Target_Type - в случае, если Вы отмечаете несколько таблиц
Target - ключ к записи, отмечаемой
Tag - текст тега

, Запросы данных были бы чем-то как:

Select distinct target from tags   
where tag in ([your list of tags to search for here])  
and target_type = [the table you're searching]

ОБНОВЛЕНИЕ
На основе Вашего требования к И условий, запрос выше превратился бы во что-то вроде этого

select target
from (
  select target, count(*) cnt 
  from tags   
  where tag in ([your list of tags to search for here])
    and target_type = [the table you're searching]
)
where cnt = [number of tags being searched]
5
ответ дан David R Tribble 23 November 2019 в 21:10
поделиться

Вы могли бы хотеть экспериментировать с not-strictly-database решением как Репозиторий содержания Java реализация (например, Американский заяц Apache ) и использовать поисковую систему, созданную к тому же как Apache Lucene.

Это решение с соответствующими механизмами кэширования возможно привело бы к лучшей производительности, чем решение собственной разработки.

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

РЕДАКТИРОВАНИЕ: с Вашим разъяснением это кажется более востребованным для использования подобного JCR решения с поисковой системой. Это значительно упростило бы Ваши программы в конечном счете.

6
ответ дан cgreeno 23 November 2019 в 21:10
поделиться

Я был бы второе @Zizzencs предположение, что Вы могли бы хотеть что-то, что это не полностью (R) центрально DB

Так или иначе, я полагаю, что использование плоскости nvarchar поля для хранения, который отмечает с некоторым надлежащим кэшированием/индексацией, могло бы привести к более быстрым результатам. Но это - просто я.

я реализовал системы меток с помощью 3 таблиц для представления отношений Many-Many прежде (Теги Объекта ItemTags), но я предполагаю, что Вы будете иметь дело с тегами в большом количестве мест, я могу сказать Вам, которые с 3 таблицами, имеющими необходимость управляться/запрашиваться одновременно все время, определенно сделают Ваш код более сложным.

Вы могли бы хотеть рассмотреть, стоит ли добавленная сложность того.

1
ответ дан chakrit 23 November 2019 в 21:10
поделиться

Вы не будете в состоянии избежать соединений и все еще быть несколько нормализованными.

Мой подход должен иметь Таблицу Тега.

 TagId (PK)| TagName (Indexed)

Затем у Вас есть столбец TagXREFID в Вашей таблице объектов.

столбцом This TagXREFID является FK к 3-й таблице, я назову его TagXREF:

 TagXrefID | ItemID | TagId

Так, для получения всех тегов для объекта было бы что-то как:

SELECT Tags.TagId,Tags.TagName 
     FROM Tags,TagXref 
     WHERE TagXref.TagId = Tags.TagId 
         AND TagXref.ItemID = @ItemID

И получить все объекты для тега, я использовал бы что-то вроде этого:

SELECT * FROM Items, TagXref
     WHERE TagXref.TagId IN 
          ( SELECT Tags.TagId FROM Tags
                WHERE Tags.TagName = @TagName; )
     AND Items.ItemId = TagXref.ItemId;

К И набор тегов вместе, Вы были бы для изменения вышеупомянутого оператора немного для добавления И Теги. TagName = @TagName1 И Теги. TagName = @TagName2 и т.д.... и динамично создают запрос.

0
ответ дан FlySwat 23 November 2019 в 21:10
поделиться

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

Items (ID pk, Name, <properties>)
Tags (ID pk, Name)
TagItems (TagID fk, ItemID fk)

, Это работает быстро в течение времени записи и сохраняет все нормализованным, но можно также отметить, что для каждого тега, Вам будет нужно к объединяющим таблицам дважды для каждого дальнейшего тега, Вы хотите И, таким образом, это имеет медленное чтение.

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

CachedTagItems(ID, Name, <properties>, tag1, tag2, ... tagN)

Тогда можно рассмотреть, как часто таблица Tagged Item должна быть усовершенствована, если это находится на каждой вставке, затем звоните, хранимая процедура в курсоре вставляют событие. Если это - почасовая задача, то настроенный работа с почасовой оплатой выполнить его.

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

В двоичном формате, легко объяснить. Скажем, существует четыре тега, которые будут присвоены объекту в двоичном файле, мы могли представить это

0000

, Если бы все четыре тега присвоены объекту, объект был бы похож на это...

1111

, Если просто первые два...

1100

Тогда это - просто случай нахождения двоичных значений с 1 с и нулями в столбце, который Вы хотите. Используя Побитовые операторы SQL Server, можно проверить, что существует 1 в первом из столбцов с помощью очень простых запросов.

Проверка эта ссылка для обнаружения [еще 115] .

0
ответ дан digiguru 23 November 2019 в 21:10
поделиться

Для перефразирования то, что сказали другие: прием не находится в схема , это находится в запрос .

наивная схема Объектов/Маркировок/Тегов является правильным способом пойти. Но поскольку Вы видели, это не сразу понятно, как выполнить И запрос с большим количеством тегов.

лучший способ оптимизировать тот запрос будет зависим от платформы, таким образом, я рекомендовал бы повторно отметить Ваш вопрос с Вашим RDBS и изменить заголовок на что-то как "Оптимальный способ выполнить И запросить на базе данных меток".

я имею несколько предложений для SQL MS, но воздержусь в случае, если это не платформа, Вы используете.

0
ответ дан Portman 23 November 2019 в 21:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: