Estoy desarrollando una aplicación que necesitará almacenar metadatos en línea e intext . Lo que quiero decir con eso es lo siguiente: digamos que tenemos un texto largo y queremos almacenar algunos metadatos relacionados con una palabra u oración específica del texto.
¿Cuál sería la mejor manera de almacenar esta información?
Mi primer pensamiento fue incluir en el texto algún tipo de Markdown
sintaxis que luego se analizaría en la recuperación. Algo parecido a esto:
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.
Esto introduciría dos problemas en los que puedo pensar:
- Una relativamente pequeña es que si dicha sintaxis se encuentra fortuitamente en dicho texto, puede interferir con el análisis.
- La más importante es que esto no mantiene estos metadatos separados del texto en sí.
Me gustaría tener una estructura de datos discreta para almacenar estos datos, una tabla de base de datos tan diferente en la que se almacenan estos metadatos, para poder usarlos de manera discreta: consultas, estadísticas, clasificación, etc.
EDITAR: Dado que el respondedor eliminó su respuesta, creo que sería bueno agregar su sugerencia aquí, ya que fue una sugerencia viable que se amplió en este primer concepto. El póster sugería usar una sintaxis similar, pero vincular los metadatos a la tabla PRIMARY KEY
de la metadata
base de datos.
Algo que se vería así:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit,
sed diam __nonummy nibh__[15432]
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Donde 15432
sería el ID
de una fila de la tabla que contiene la información necesaria y consultable, como en el ejemplo a continuación.
Mi segundo pensamiento fue almacenar información de este tipo en una tabla de DB con el siguiente aspecto:
TABLE: metadata
ID TEXT_ID TYPE OFFSET_START OFFSET_END CONTENT
1 lipsum note 68 79 this sounds really funny latin
De esta forma, los metadatos tendrían una identificación única, text_id
como una clave externa conectada a la tabla que almacena los textos y conectaría los datos con el texto en sí mismo utilizando un rango de desplazamiento de caracteres simple .
Esto haría el truco de mantener los datos separados de los metadatos , pero un problema que puedo ver inmediatamente con este enfoque es que el texto básicamente no sería editable . O, si quisiera implementar la edición del texto después de la asignación de metadatos, básicamente tendría que calcular la adición o eliminación de caracteres en comparación con la versión anterior, y verificar si cada una de estas modificaciones agrega o elimina caracteres antes o después de cada de los metadatos asociados.
Lo cual, para mí, suena como un enfoque realmente poco elegante.
¿Tiene alguna sugerencia o sugerencia sobre cómo podría abordar el problema?
Edición 2: algunos problemas XML
Agregar otro caso que haría bastante necesario que esta separación de datos y metadatos suceda.
- Digamos que quiero hacer posible que diferentes usuarios tengan diferentes conjuntos de metadatos del mismo texto , con o sin la posibilidad de que cada usuario muestre los metadatos del otro usuario.
Cualquier solución del tipo de descuento (o HTML, o XML) sería difícil de implementar en este momento. La única solución en este caso en la que podría pensar sería tener otra tabla DB que contendría la versión de un solo usuario del texto original, conectándose a la tabla de texto original mediante el uso de a FOREIGN KEY
.
No estoy seguro si esto es muy elegante tampoco.
- XML tiene un modelo de datos jerárquico: cualquier elemento que se encuentre dentro de los límites de otro elemento se considera hijo , lo que no suele ser el caso en el modelo de datos que estoy buscando; en cualquier XML hijos elemento debe estar cerrada antes de que el padre etiqueta puede ser cerrado, lo que permite sin superposición de elementos.
Ejemplo:
<note content="the beginning of the famous placeholder">
Lorem ipsum dolor sit<comment content="I like the sound of amet/elit">
amet</note>
, consectetuer adipiscing elit</comment>
,<note content="adversative?">
sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.<note content="funny latin">
</note>
</note>
Aquí tenemos dos problemas diferentes:
Superposición de diferentes elementos: el primer comentario comienza dentro de la primera nota, pero termina después del final de la primera nota, es decir, no es su hijo.
Los mismos elementos se superponen: la última nota y la nota en negrita se superponen; sin embargo, dado que son el mismo tipo de elemento, el analizador cerraría el último elemento abierto en el primer cierre, y el primer elemento abierto en el último cierre, que, en esta circunstancia, no es lo que se pretende.
fuente
Respuestas:
Buscaría una combinación de sus soluciones, pero en su lugar, usaría un estándar: XML. Tendrías una sintaxis como esta
Por qué XML
Si lo piensa, es exactamente cómo está estructurada toda la web : contenido (texto real) que lleva semántica, lo que llama metadatos , a través de etiquetas html.
De esta manera tienes un mundo realmente genial que se abre:
Lorem <note>ipsum</note>
se genera cuando está buscando,lorem ips*
por ejemplo.Por qué XML sobre Markdown
Un sitio web como stackexchange usa markdown ya que la semántica que transmite su contenido es bastante básica: énfasis, enlaces / URL, imagen, encabezado, etc. Parece que la semántica que está agregando a su contenido es
Por lo tanto, siento que Markdown no sería una muy buena idea. Además, Markdown no está realmente estandarizado, y analizar / descargar puede ser un dolor de cabeza, incluso una sintaxis más marcada ver la publicación de Jeff Atwood sobre el WTF que conoció al analizar Markdown .
Sobre la separación entre datos y metadatos
Per se, tal separación no es obligatoria. Supongo que está buscando la ventaja que trae:
Todas estas preocupaciones se resuelven mediante el uso de XML. Desde el XML, puede volcar fácilmente cualquier contenido despojado de etiquetas, y los datos / metadatos están separados, al igual que el atributo y el texto real está separado en XML.
Además, no creo que realmente pueda tener sus metadatos totalmente no vinculados a sus datos . Por lo que describe, sus metadatos son una composición de sus datos, es decir, eliminar los datos conduce a la eliminación de metadatos. Aquí es donde los metadatos divergen del HTML / CSS habitual. CSS no desaparece cuando se elimina un elemento html, porque puede aplicarse a otros elementos. No creo que este sea el caso en sus metadatos.
Tener metadatos cercanos a los datos, como en XML o Markdown, permite una fácil comprensión (y quizás depuración) de los datos. Además, el ejemplo que da en su segundo pensamiento agrega cierta complejidad, porque para cada dato que estoy leyendo, necesito consultar la tabla de metadatos para obtenerlos. Si la relación entre sus datos y sus metadatos es 1: 1 o 1: N, entonces es IMO claramente inútil, y solo trae complejidad (un buen caso de YAGNI).
fuente
El caso de uso de la solución
No estoy de acuerdo con algunas de las otras respuestas, simplemente porque, si bien son excelentes soluciones, probablemente no sean su solución. Sí, XML tiene la marca de palabra en sus siglas, pero probablemente no sea ideal para su situación. Es demasiado complejo, ofrece poca ayuda para mantener los metadatos separados del texto original. Básicamente, convertirá todo en una forma de metadatos, creando un conjunto de datos con sobrepeso.
Como es probable que no haya una solución o enfoque absolutamente correcto, la mejor solución responde a la pregunta:
Además, si intenta preguntar, cómo un diseño de solución podría agregar de manera inherente al valor del sistema, en la forma en que se utilizará, entonces está más cerca de encontrar su respuesta elegante .
Entendiendo el problema
Ok suficiente comentario, profundicemos en el problema. Este es el problema tal como lo entiendo (obviamente, agregarlo será beneficioso):
Construyendo el diseño de la solución
Comprendiendo el problema como lo he descrito anteriormente, ahora comenzaré a sugerir posibles soluciones y enfoques que tengan como objetivo resolver el problema anterior.
Componentes
Por lo tanto, vería que debería haber un sistema de acceso de usuario personalizado. Filtraría metadatos relevantes e irrelevantes del texto original. Facilitaría la edición y visualización de metadatos en el texto. Aseguraría la integridad de la relación entre los metadatos y su texto original. Estructuraría los metadatos y ofrecería una fuente de datos a un sistema de datos relacionales. Lo más probable es que proporcione una gran cantidad de otras funciones orientadas a un propósito.
Estructura
Por lo tanto, dado que es importante mantener la integridad de los metadatos en el texto original, la mejor manera de garantizar esto es mantener los metadatos en línea con el texto original. Esto ofrecerá el beneficio de que los datos originales se pueden editar con confianza sin romper esta integridad.
Las preocupaciones con este enfoque son la corrupción de los metadatos por los datos originales y viceversa. La adecuada indexación y estructuración de los metadatos y sus (meta) metadatos de una manera que permita consultas y actualizaciones y un acceso eficiente. El fácil filtrado de metadatos del texto original.
Con esto en mente, sugeriría que una parte de la solución se base en el enfoque de usar PERSONAJES DE ESCAPE dentro del texto original. Esto no es lo mismo que diseñar su propio lenguaje de marcado o usar un lenguaje de marcado existente como XML o HTML. Es fácil diseñar un CARÁCTER DE ESCAPE que tenga una probabilidad de cero o casi cero de existir en el texto original.
Datos de ejemplo con secuencias de escape
Esta es una historia de un hombre. >>>> (#) ¿Por qué es esta historia sobre un hombre y no una mujer? (#) ( ) Userid :: 77367 ( ) Comentario del gerente ( ) DataID :: 234234234 >>>> Un hombre que fue a cortar un prado, Fui a cortar un prado. El hombre fue con su perro >>>> (#) Pregúntele al cliente si la historia sería mejor con un gato (#) >>>> para cortar el prado. Así que ahora esta es la historia de un hombre y su perro que fueron a cortar un prado.
Un hombre y su perro, fueron a cortar un prado, fueron a cortar un prado, un prado alcanzado sobre la montaña. >>>> (#) Esto suena mucho mejor con un bosque (**) Sugerencia Nota (#) >>>>
El hombre y su perro y su misión, para cortar un prado, un prado alcanzado sobre la montaña solo se alcanza al cruzar el río.
Datos de ejemplo sin secuencias de escape
Esta es una historia de un hombre. Un hombre que fue a cortar un prado, fue a cortar un prado. El hombre fue con su perro a cortar el prado. Así que ahora esta es la historia de un hombre y su perro que fueron a cortar un prado.
Un hombre y su perro, fueron a cortar un prado, fueron a cortar un prado, un prado alcanzado sobre la montaña.
El hombre y su perro y su misión, para cortar un prado, un prado alcanzado sobre la montaña solo se alcanza al cruzar el río.
Obviamente, esto se analiza fácilmente, no es complejo como un lenguaje de marcado completo y se adapta fácilmente a su propósito.
Resuelto todavía? Bueno, yo diría que no. Nuestra solución todavía tiene algunos agujeros. La indexación y el acceso estructurado de estos datos es deficiente. Además, no sería razonable consultar este archivo (o varios archivos) al mismo tiempo que lo edita.
¿Cómo podríamos resolver ese problema?
Sugeriría una TABLA DE ASIGNACIÓN DE DATOS como encabezado del documento. También sugeriría implementar una COLA DE ACTUALIZACIÓN DE TABLA TRANSACCIONAL . Dejame explicar. Los diseñadores de un sistema de archivos, particularmente un sistema de archivos de disco rotativo, enfrentaron desafíos de diseño similares a los que usted describió anteriormente. Necesitaban insertar información sobre los archivos en el disco junto con los datos. Una gran solución para la integridad de la relación de estos datos fue DUPLICARLA en una Tabla de asignación de archivos (FAT).
Esto significa que para cada elemento de metadatos individual, hay una entrada correspondiente en la tabla de asignación de datos . Por lo tanto, es rápido, estructurado y relacional, e independiente de los datos originales. Si es necesario realizar consultas, uniones o actualizaciones en los metadatos, entonces se hace fácilmente simplemente accediendo a la Tabla de asignación de datos .
Obviamente, se debe tener cuidado para garantizar que los metadatos en línea originales sean un reflejo verdadero de los datos de la tabla de asignación de datos. Ahí es donde entra en juego una Cola de actualización de tabla transaccional. Cada cambio, adición o eliminación de metadatos no se realiza en los datos en sí, sino en la cola. la cola se asegurará de que se realicen todos los cambios en los datos en línea y en la tabla, o que no se realice ningún cambio. También permite realizar actualizaciones asincrónicas, por ejemplo, todos los metadatos de un determinado usuario se pueden eliminar ejecutando un comando de eliminación en la cola. Si los metadatos en línea estaban bloqueados y en uso, la cola no realizaría ningún cambio hasta que pudiera hacerlo tanto en los datos de la tabla como en los datos en línea.
fuente
>>>>>(#1) Lorem ipsum (#1)>>>>>>
. Además, parece que su enfoque en los comentarios de texto los obligaría a unirse a una determinada posición fija, ¿cómo funcionaría eso si se mueve el desplazamiento?Este es un tipo típico de pregunta de ingeniería en el sentido de que todas sus opciones tienen diferentes compensaciones, y cuál es la mejor depende de lo que sea importante para usted. Desafortunadamente, no ha brindado suficiente información para tomar la determinación.
Tampoco parece haber considerado un problema semántico importante. Digamos que el texto original es
Alguien agrega un comentario sobre "Bob" diciendo
Luego, el texto original se edita en
Usted puede tener un cierto sentido de este caso particular, el uso de un algoritmo de coincidencia de texto como lo que se utiliza para mostrar un archivo diff, pero las compensaciones de carácter van a hacer que los metadatos se adhieren a la "Jan" en "Jane".
Peor es si el texto se edita en
Podrías averiguar cómo adjuntar los metadatos a "Steve", pero ¿cómo sabes si corresponde?
Además, ¿ha decidido si los metadatos en sí mismos pueden tener metadatos? Eso podría cambiar su implementación.
Más allá de los problemas semánticos, no está muy claro lo que está haciendo con los datos. Pensé que tal vez era muy inconveniente tener el texto original "contaminado" con cualquier marcado, pero estaba de acuerdo con tener valores de ID en él. Lo que no tiene mucho sentido si los metadatos se aplican a una sección de texto en lugar de insertarse en un punto del texto.
Supongo que, para la mayoría de los propósitos, almacenar texto marcado es más fácil o, como segunda opción, pasar todo SQL y tener el texto y el marcado representados por una jerarquía de nodos, básicamente un DOM en forma de tabla. Si sus datos son jerárquicos, puede ser más fácil usar XML y obtener analizadores existentes de forma gratuita, en lugar de escribir el suyo propio.
Es bastante posible que haya una solución bastante simple que sea lo suficientemente buena para su situación exacta, pero no puedo decirle qué es eso porque realmente depende de lo que está tratando de hacer, en detalle.
Te sugiero encapsular cualquier estrategia que elijas tanto como puedas, aunque esto es bastante difícil de hacer si gran parte de tu implementación necesita ser visible para muchas consultas SQL.
Lamento que la respuesta esté tan dispersa y tan llena de "depende", pero las preguntas de diseño del mundo real son así.
fuente
Creo que la sugerencia del contestador anterior, la que menciona en su pregunta) es muy buena.
Se comportaría de la misma manera que publicamos enlaces en los sitios de StackExchange, pero los datos de información estarían en otra tabla. Los beneficios son que tiene los datos separados y, por lo tanto, consultables e indexables. Al editar el texto, puede verificar si hay ID de metadatos eliminados y limpiar la tabla de metadatos.
El único pequeño problema como usted dijo es el análisis, pero puede solucionarlo con bastante facilidad.
fuente
Digamos que tengo un texto:
Añado la nota así:
[@123,#456,2w]
significa: user_id = 123, note_id = 456, y el texto marcado por esta nota abarca las siguientes 2 palabras (podrían ser caracteres (c
), oraciones (s
), paragraps (p
) o lo que sea). La sintaxis exacta puede ser diferente, por supuesto.En los editores de texto plano, el texto de las notas se puede almacenar fácilmente al final del documento, al igual que con las notas al pie de Markdown.
En los editores de texto enriquecido, este tipo de nota se puede mostrar en el texto como un icono, y el texto marcado se puede resaltar de alguna manera. El usuario puede eliminar esas notas como caracteres normales con Delo Backspace, y editarlas con algún tipo de modo de edición especial. Me imagino cambiar el tamaño de las áreas señaladas con un mouse y editar el texto de la nota con una ventana emergente.
Pros:
Contras para la edición de texto sin formato:
Contras generales:
fuente
nonummy
ynibh
, no se estropearía con mis compensaciones?