Я разрабатываю приложение , которое нужно будет хранить рядный , Intext метаданных. Под этим я подразумеваю следующее: допустим, у нас есть длинный текст, и мы хотим сохранить некоторые метаданные, связанные с определенным словом или предложением текста.
Как лучше всего хранить эту информацию?
Моей первой мыслью было включить в текст некий Markdown
синтаксис , который затем будет проанализирован при извлечении. Что-то похожее на это:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit,
sed diam __nonummy nibh__[@note this sounds really funny latin]
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Это может привести к двум проблемам:
- Относительно небольшим является то, что если указанный синтаксис случайно оказался в указанном тексте, он может испортить синтаксический анализ.
- Наиболее важным является то, что это не поддерживает эти метаданные отдельно от самого текста.
Я хотел бы иметь дискретную структуру данных для хранения этих данных, такую как другая таблица БД, в которой хранятся эти метаданные, чтобы я мог использовать их по-разному: запросы, статистика, сортировка и так далее.
РЕДАКТИРОВАТЬ: Поскольку ответчик удалил свой ответ, я думаю, что было бы неплохо добавить его предложение здесь, так как это было реальное предложение, которое расширило эту первую концепцию. Плакат предложил использовать подобный синтаксис, но связать метаданные к PRIMARY KEY
из metadata
таблицы базы данных.
Нечто похожее на это:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit,
sed diam __nonummy nibh__[15432]
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Где 15432
будет находиться ID
строка таблицы, содержащая необходимую запрашиваемую информацию, как показано в примере ниже.
Моя вторая мысль заключалась в том, чтобы хранить информацию такого рода в таблице БД, которая выглядит следующим образом:
TABLE: metadata
ID TEXT_ID TYPE OFFSET_START OFFSET_END CONTENT
1 lipsum note 68 79 this sounds really funny latin
Таким образом, метаданные будут иметь уникальный идентификатор, text_id
как внешний ключ, связанный с таблицей, в которой хранятся тексты, и он будет связывать данные с самим текстом, используя простой диапазон смещения символов .
Это позволило бы отделить данные от метаданных , но проблема, которую я сразу вижу при таком подходе, заключается в том, что текст в принципе не подлежит редактированию . Или, если бы я захотел осуществить редактирование текста после назначения метаданных, мне пришлось бы в основном рассчитывать добавление или удаление символов по сравнению с предыдущей версией и проверять, добавляет ли каждая из этих модификаций символы или удаляет их до или после каждого из них. связанных метаданных.
Что для меня звучит как по-настоящему не элегантный подход.
Есть ли у вас какие-либо указания или предложения о том, как я мог бы подойти к проблеме?
Редактировать 2: некоторые проблемы с XML
Добавление еще одного случая, который сделал бы совершенно необходимым для такого разделения данных и метаданных.
- Допустим, я хочу, чтобы разные пользователи могли иметь разные наборы метаданных одного и того же текста , с возможностью или без возможности каждого пользователя фактически отображать метаданные другого пользователя.
Любое решение типа уценки (или HTML, или XML) было бы трудно реализовать на данном этапе. Единственное решение в этом случае, о котором я мог подумать, - это иметь еще одну таблицу БД, которая будет содержать однопользовательскую версию исходного текста, соединяющуюся с исходной текстовой таблицей с помощью a FOREIGN KEY
.
Не уверен, что это очень элегантно.
- У XML есть иерархическая модель данных: любой элемент, который оказывается в границах другого элемента, рассматривается как его дочерний элемент , что чаще всего не соответствует той модели данных, которую я ищу; в XML любой дочерний элемент должен быть закрыт до того, как родительский тег может быть закрыт, не допуская перекрытия элементов.
Пример:
<note content="the beginning of the famous placeholder">
Lorem ipsum dolor sit<comment content="I like the sound of amet/elit">
amet</note>
, посвященный адептированию elit</comment>
,<note content="adversative?">
sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.<note content="funny latin">
</note>
</note>
Здесь у нас есть две разные проблемы:
Различные элементы перекрываются: первый комментарий начинается в первой заметке, но заканчивается после окончания первой, т. Е. Это не его дочерний элемент.
Одинаковые элементы перекрываются: последняя нота и полужирная нота перекрываются; однако, поскольку они являются элементом одного типа, синтаксический анализатор закроет последний открытый элемент при первом закрытии, а первый открытый элемент - при последнем закрытии, что в данном случае не является тем, что предназначено.
источник
Ответы:
Я бы выбрал сочетание ваших решений, но вместо этого я бы использовал стандарт: XML. У вас будет такой синтаксис
Почему XML
Если вы подумаете об этом, это именно то, как структурирована вся сеть : контент (фактический текст), который несет семантическую - то, что вы называете метаданными - через HTML-теги.
Таким образом, у вас есть действительно крутой мир, который открывается:
Lorem <note>ipsum</note>
поднимается, когда вы ищете,lorem ips*
например.Почему XML по уценке
Веб-сайт, такой как stackexchange, использует разметку, поскольку семантика, которую передает его контент, довольно проста: выделение, ссылки / URL-адреса, изображение, заголовок и т. Д.
Таким образом, я чувствую, что Markdown не будет хорошей идеей. Кроме того, Markdown на самом деле не стандартизирован, и его анализ / сброс могут быть проблемой в заднице, даже более унылым синтаксисом, см . Пост Джеффа Этвуда о WTF, который он встретил при анализе Markdown .
О разделении данных и метаданных
По сути, такое разделение не является обязательным. Я полагаю, вы ищете преимущество, которое оно приносит:
Все эти проблемы устраняются с помощью XML. Из XML вы можете легко вывести любой контент, лишенный тегов, и данные / метаданные разделены, точно так же, как атрибут и фактический текст разделены в XML.
Кроме того, я не думаю, что ваши метаданные могут быть абсолютно не привязаны к вашим данным . Из того, что вы описываете, ваши метаданные представляют собой композицию ваших данных, то есть удаление данных приводит к удалению метаданных. Здесь метаданные расходятся с обычным HTML / CSS. CSS не исчезает при удалении html-элемента, потому что он может быть применен к другим элементам. Я не чувствую, что это так в ваших метаданных.
Наличие метаданных, близких к данным, как в XML или Markdown, позволяет легко понять (и, возможно, отладить) данные. Кроме того, пример, который вы привели со своей второй мыслью, добавляет некоторую сложность, потому что для каждых данных, которые я читаю, мне нужно запросить таблицу метаданных, чтобы получить их. Если отношение между вашими данными и вашими метаданными составляет 1: 1 или 1: N, то это IMO, очевидно, бесполезно и приносит только сложность (хороший случай YAGNI).
источник
Вариант использования решения
Я не согласен с некоторыми другими ответами, просто потому что, хотя отличные решения, они, вероятно, не ваше решение. Да, у XML есть разметка слова в его аббревиатуре, но это, вероятно, не идеально для вашей ситуации. Он слишком сложный, он мало помогает в хранении метаданных отдельно от исходного текста. По сути это превратит все в форму метаданных, создав один избыточный набор данных.
Поскольку, вероятно, не существует абсолютно правильного решения или подхода, лучшее решение отвечает на вопрос:
Кроме того, если вы попытаетесь спросить, как дизайн решения может по своей сути повысить ценность системы и то, как она будет использоваться, тогда вы ближе к поиску своего элегантного ответа.
Понимание проблемы
Хорошо, достаточно комментариев, давайте углубимся в проблему. Это проблема, насколько я понимаю (очевидно, что добавление к ней будет полезно):
Построение дизайна решения
Понимая проблему, как я обрисовал ее выше, я сейчас начну предлагать возможные решения и подходы, направленные на решение вышеуказанной проблемы.
Компоненты
Таким образом, я бы увидел, что должна быть специально построенная система доступа пользователей. Это отфильтровывает релевантные и нерелевантные метаданные из исходного текста. Это облегчит редактирование и просмотр метаданных в тексте. Это обеспечит целостность отношений между метаданными и их оригинальным текстом. Он структурирует метаданные и предоставит источник данных для реляционной системы данных. Скорее всего, он предоставит множество других функций, управляемых целью.
Структура
Поэтому, поскольку важно сохранить целостность метаданных по отношению к исходному тексту, лучший способ обеспечить это - поддерживать метаданные в соответствии с исходным текстом. Это даст преимущество в том, что исходные данные можно уверенно редактировать, не нарушая эту целостность.
Проблемы с этим подходом связаны с искажением метаданных исходными данными и наоборот. Адекватное индексирование и структурирование метаданных и их (мета) метаданных таким образом, чтобы обеспечить запросы и обновления и эффективный доступ. Простая фильтрация метаданных из исходного текста.
Имея это в виду, я бы предложил, чтобы часть решения основывалась на подходе использования ESCAPE CHARACTERS в исходном тексте. Это не то же самое, что разработка собственного языка разметки или использование существующего языка разметки, такого как XML или HTML. Легко спроектировать ESCAPE CHARACTER с нулевым или почти нулевым шансом существования в исходном тексте.
Пример данных с Escape-последовательностями
Это история человека. >>>> (#) Почему эта история о мужчине, а не женщине? (#) ( ) Userid :: 77367 ( ) Комментарий менеджера ( ) DataID :: 234234234 >>>> Человек, который пошел косить луг, пошел косить луг. Человек пошел со своей собакой >>>> (#) Спросите клиента, будет ли лучше история с кошкой (#) >>>> косить луг. Итак, теперь это история о человеке и его собаке, которые пошли косить луг.
Один человек и его собака пошли косить луг, косить луг, луг достиг горы. >>>> (#) Звучит лучше с лесом (**) Примечание для заметки (#) >>>>
Человек и его собака и его миссия - косить луг, луг, достигающий горы, достигается только при пересечении реки.
Пример данных без Escape-последовательностей
Это история человека. Человек, который пошел косить луг, пошел косить луг. Человек пошел со своей собакой косить луг. Итак, теперь это история о человеке и его собаке, которые пошли косить луг.
Один человек и его собака пошли косить луг, косить луг, луг достиг горы.
Человек и его собака и его миссия - косить луг, луг, достигающий горы, достигается только при пересечении реки.
Очевидно, что это легко разбирается, не является сложным как весь язык разметки и легко адаптируется к вашей цели.
Решено еще? Ну, я бы сказал, нет. В нашем решении все еще есть дыры. Индексирование и структурированный доступ к этим данным оставляет желать лучшего. Кроме того, было бы неразумно запрашивать этот файл (или несколько файлов) одновременно с редактированием.
Как мы можем решить эту проблему?
Я бы предложил таблицу размещения данных в качестве заголовка документа. Я бы также предложил внедрить ТРАНЗАКЦИОННУЮ ОЧЕРЕДЬ ОБНОВЛЕНИЯ ТАБЛИЦ . Позволь мне объяснить. Разработчики файловой системы, в частности файловой системы с вращающимся диском, столкнулись с проблемами проектирования, аналогичными тем, которые вы описали выше. Им нужно было вставить информацию о файлах на диск вместе с данными. Отличным решением для целостности отношений этих данных было ДУБЛИРОВАТЬ их в Таблице размещения файлов (FAT).
Это означает, что для каждого отдельного элемента метаданных есть соответствующая запись в таблице распределения данных . Так что это быстро, структурировано и реляционно, и не зависит от исходных данных. Если необходимо выполнить запросы, объединения или обновления метаданных, то это легко сделать, просто открыв таблицу распределения данных .
Очевидно, следует позаботиться о том, чтобы исходные встроенные метаданные являлись истинным отражением данных таблицы распределения данных. Вот где приходит очередь обновления транзакционной таблицы. Каждое изменение, добавление или удаление метаданных производится не на самих данных, а на очереди. затем очередь будет гарантировать, что либо все изменения будут внесены как в данные в строке, так и в данные таблицы, либо вообще не будут внесены изменения. Это также позволяет выполнять асинхронные обновления, например, все метаданные определенного пользователя могут быть удалены с помощью команды удаления в очереди. Если встроенные метаданные были заблокированы и использовались, очередь не будет вносить никаких изменений, пока не сможет сделать это как с данными таблицы, так и с встроенными данными.
источник
>>>>>(#1) Lorem ipsum (#1)>>>>>>
. Кроме того, похоже, что ваш подход в целочисленных комментариях будет привязывать их к определенной фиксированной позиции, как это будет работать при перемещении смещения?Это типичный технический вопрос, поскольку все ваши варианты имеют разные компромиссы, и что лучше всего зависит от того, что важно для вас. К сожалению, вы не дали достаточно информации, чтобы принять решение.
Вы также, кажется, не рассматривали важную семантическую проблему. Допустим, оригинальный текст
Кто-то добавляет комментарий вокруг «Боб», говоря
Затем исходный текст редактируется в
Вы можете иметь некоторый смысл в этом конкретном случае, используя алгоритм сопоставления текста, например, используемый для отображения файла сравнения, но смещение символов приведет к тому, что метаданные присоединятся к «Jan» в «Jane».
Хуже, если текст редактируется в
Вы могли бы понять, как прикрепить метаданные к «Стиву», но как узнать, применимо ли это?
Кроме того, вы решили, могут ли метаданные иметь метаданные? Это может изменить вашу реализацию.
Помимо семантических проблем, не очень понятно, что вы делаете с данными. Я подумал, что, возможно, было очень неудобно, чтобы исходный текст был «загрязнен» какой-либо разметкой, но тогда вы были в порядке с наличием значений ID в нем. Что не имеет большого смысла, если метаданные применяются к части текста, а не вставляются в точку в тексте.
Я предполагаю, что для большинства целей проще хранить размеченный текст или, во-вторых, использовать весь SQL-код и представлять текст и разметку в виде иерархии узлов - в основном DOM в форме таблицы. Если ваши данные иерархичны, то, возможно, будет проще использовать XML и получать существующие парсеры бесплатно, а не писать свои собственные.
Вполне возможно, что есть какое-то довольно простое решение, которое достаточно подходит для вашей конкретной ситуации, но я не могу сказать вам, что это такое, потому что оно действительно зависит от того, что вы пытаетесь сделать, в деталях.
Я настоятельно рекомендую вам как можно больше инкапсулировать любую выбранную вами стратегию, хотя это довольно сложно сделать, если большая часть вашей реализации должна быть видимой для многих запросов SQL.
Извините, что ответ так разбросан и полон "это зависит", но вопросы дизайна реального мира такие.
источник
Я думаю, что предложение предыдущего ответчика, которое вы упоминаете по вашему вопросу), очень хорошее.
Он будет вести себя так же, как мы публикуем ссылки на сайтах StackExchange, но информационные данные будут находиться в другой таблице. Преимущества заключаются в том, что у вас есть отдельные данные, и, следовательно, возможность запроса и индексации. При редактировании текста вы можете проверить наличие удаленных идентификаторов метаданных и очистить таблицу метаданных.
Единственная небольшая проблема, как вы сказали, - это разбор, но вы можете справиться с ней довольно легко.
источник
Допустим, у меня есть текст:
Я добавляю записку так:
[@123,#456,2w]
означает: user_id = 123, note_id = 456, а текст, помеченный этой заметкой, охватывает следующие 2 слова (может быть chars (c
), фраз (s
), параграпов (p
) или что угодно). Точный синтаксис может быть разным, конечно.В текстовых редакторах текст заметок может быть легко сохранен в конце документа, как в сносках Markdown.
В редакторах форматированного текста этот вид заметки может отображаться в тексте в виде значка, а помеченный текст может быть выделен некоторым образом. Затем пользователь может удалять такие заметки, как обычные символы, с помощью Delили Backspace, и редактировать их в каком-то особом режиме редактирования. Я представляю изменение размеров отмеченных областей с помощью мыши и редактирование текста заметки с помощью всплывающего окна.
Плюсы:
Минусы для редактирования простого текста:
Общие минусы:
источник
nonummy
иnibh
, не испортит ли это мои смещения?