Estou desenvolvendo um aplicativo que precisará armazenar metadados em linha e intext . O que quero dizer com isso é o seguinte: digamos que temos um texto longo e queremos armazenar alguns metadados conectados a uma palavra ou sentença específica do texto.
Qual seria a melhor maneira de armazenar essas informações?
Meu primeiro pensamento foi incluir no texto algum tipo de Markdown
sintaxe que seria analisada na recuperação. Algo parecido com isto:
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.
Isso introduziria dois problemas que posso pensar:
- Uma relativamente pequena, é que, se a referida sintaxe estiver fortuitamente no texto mencionado, ela poderá interferir na análise.
- O mais importante é que isso não mantém esses metadados separados do próprio texto.
Eu gostaria de ter uma estrutura de dados discreta para armazenar esses dados, uma tabela de banco de dados diferente na qual esses metadados são armazenados, para que eu possa usá-los de maneiras distintas: consultas, estatísticas, classificação e assim por diante.
EDIT: Como o respondente excluiu sua resposta, acho que seria bom adicionar sua sugestão aqui, pois foi uma sugestão viável que se expandiu nesse primeiro conceito. O pôster sugeriu usar uma sintaxe semelhante, mas vincular os metadados à tabela PRIMARY KEY
do metadata
banco de dados.
Algo que seria assim:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit,
sed diam __nonummy nibh__[15432]
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Onde 15432
seria a ID
linha de uma tabela que contém as informações necessárias e passíveis de consulta, como no exemplo abaixo.
Meu segundo pensamento foi armazenar informações desse tipo em uma tabela de banco de dados assim:
TABLE: metadata
ID TEXT_ID TYPE OFFSET_START OFFSET_END CONTENT
1 lipsum note 68 79 this sounds really funny latin
Dessa maneira, os metadados teriam um ID exclusivo, text_id
como uma chave estrangeira conectada à tabela que armazena os textos e conectaria os dados ao próprio texto usando um intervalo simples de deslocamento de caracteres .
Isso faria o truque de manter os dados separados dos metadados , mas um problema que posso ver imediatamente com essa abordagem é que o texto seria fundamentalmente não editável . Ou, se eu quisesse implementar a edição do texto após a atribuição dos metadados, basicamente precisaria calcular adições ou remoção de caracteres em comparação com a versão anterior e verificar se cada uma dessas modificações adiciona ou remove caracteres antes ou depois de cada dos metadados associados.
O que, para mim, parece uma abordagem realmente deselegante.
Você tem alguma sugestão ou sugestão de como eu poderia abordar o problema?
Edit 2: alguns problemas de XML
Adicionar outro caso que tornaria bastante necessário para essa separação de dados e metadados.
- Digamos que eu queira possibilitar que diferentes usuários tenham diferentes conjuntos de metadados do mesmo texto , com ou sem a possibilidade de cada usuário realmente exibir os outros metadados do usuário.
Qualquer solução do tipo de remarcação (ou HTML ou XML) seria difícil de implementar neste momento. A única solução nesse caso em que eu poderia pensar seria ter outra tabela de banco de dados que contivesse a versão de usuário único do texto original, conectando-se à tabela de texto original pelo uso de a FOREIGN KEY
.
Não tenho certeza se isso é muito elegante também.
- O XML possui um modelo de dados hierárquico: qualquer elemento que esteja dentro das bordas de outro elemento é considerado filho , o que geralmente não é o caso no modelo de dados que estou procurando; em XML, qualquer elemento filho deve ser fechado antes que a tag pai possa ser fechada, não permitindo sobreposição de elementos.
Exemplo:
<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>
Aqui temos dois problemas diferentes:
Sobreposição de diferentes elementos: O primeiro comentário começa na primeira nota, mas termina após o final da primeira nota, ou seja, não é filho.
Os mesmos elementos se sobrepõem: a última nota e a nota em negrito se sobrepõem; no entanto, como são o mesmo tipo de elemento, o analisador fecharia o último elemento aberto no primeiro fechamento e o primeiro elemento aberto no último fechamento, o que, nessa circunstância, não é o que se destina.
fonte
Respostas:
Eu usaria uma mistura de suas soluções, mas usaria um padrão: XML. Você teria uma sintaxe como esta
Por que XML
Se você pensar bem, é exatamente como toda a Web está estruturada : conteúdo (texto real) que carrega semântica - o que você está chamando de metadados - através de tags html.
Dessa forma, você tem um mundo muito legal que se abre:
Lorem <note>ipsum</note>
é gerado quando você está procurando,lorem ips*
por exemplo.Por que XML sobre Markdown
Um site como o stackexchange usa markdown como a semântica que seu conteúdo transmite é bastante básica: ênfase, links / URLs, imagem, cabeçalho etc. Parece que a semântica que você está adicionando ao seu conteúdo é
Portanto, sinto que Markdown não seria uma boa idéia. Além disso, o Markdown não é realmente padronizado, e analisar / despejar pode ser um problema, ainda mais uma sintaxe de markdownish, veja o post de Jeff Atwood sobre o WTF que ele conheceu ao analisar o Markdown .
Na separação entre dados e metadados
Por si só, essa separação não é obrigatória. Presumo que você esteja procurando a vantagem que ela traz:
Todas essas preocupações são esclarecidas pelo uso de XML. No XML, você pode despejar com facilidade qualquer conteúdo sem tags e os dados / metadados são separados, assim como o atributo e o texto real são separados em XML.
Também não acho que você possa realmente ter seus metadados totalmente não vinculados aos seus dados . Pelo que você descreve, seus metadados são uma composição de seus dados, ou seja, excluir os dados leva à exclusão de metadados. É aqui que os metadados divergem do HTML / CSS usual. O CSS não desaparece quando um elemento html é removido, porque pode ser aplicado a outros elementos. Não acho que esse seja o caso dos seus metadados.
Ter metadados próximos aos dados, como em XML ou Markdown, permite uma fácil compreensão (e talvez depuração) dos dados. Além disso, o exemplo que você dá ao seu segundo pensamento adiciona alguma complexidade, porque para cada dado que estou lendo, preciso consultar a tabela de metadados para obtê-los. Se a relação entre seus dados e seus metadados for 1: 1 ou 1: N, é IMO claramente inútil e traz apenas complexidade (um bom caso do YAGNI).
fonte
O Caso de Uso da Solução
Discordo de algumas das outras respostas, simplesmente porque, embora sejam ótimas soluções, elas provavelmente não são a sua solução. Sim, XML possui a marcação de palavras em sua sigla, mas provavelmente não é o ideal para sua situação. É muito complexo, oferece pouca assistência para manter os metadados separados do texto original. Essencialmente, transformará tudo em uma forma de metadados, criando um conjunto de dados com excesso de peso.
Como provavelmente não existe uma solução ou abordagem absolutamente correta, a melhor solução responde à pergunta:
Além disso, se você tentar perguntar, como um design de solução poderia inerentemente agregar ao valor do sistema, da maneira que ele será usado, você estará mais perto de encontrar sua resposta elegante .
Compreendendo o problema
Ok, comentário suficiente, vamos nos aprofundar no problema. Este é o problema que eu entendo (obviamente, adicionar isso será benéfico):
Construindo o design da solução
Entendendo o problema como o descrevi acima, agora começarei a sugerir possíveis soluções e abordagens que visam solucionar o problema acima.
Componentes
Então, eu veria que seria necessário um sistema de acesso de usuário personalizado. Ele filtraria metadados relevantes e irrelevantes do texto original. Facilitaria a edição e visualização de metadados no texto. Isso garantiria a integridade do relacionamento entre os metadados e o texto original. Estruturaria os metadados e ofereceria uma fonte de dados para um sistema de dados relacionais. Provavelmente fornecerá uma série de outras funções direcionadas a propósitos.
Estrutura
Portanto, como é importante manter a integridade dos metadados no texto original, a melhor maneira de garantir isso é manter os metadados alinhados com o texto original. Isso oferecerá o benefício de que os dados originais podem ser editados com segurança sem quebrar essa integridade.
As preocupações com essa abordagem são a corrupção dos metadados pelos dados originais e vice-versa. A indexação e estruturação adequadas dos metadados e seus (meta) metadados de forma a permitir consultas e atualizações e acesso eficiente. A filtragem fácil de metadados do texto original.
Com isso em mente, sugiro que uma parte da solução seja baseada na abordagem do uso de ESCAPE CHARACTERS no texto original. Isso não é o mesmo que criar sua própria linguagem de marcação ou usar uma linguagem de marcação existente, como XML ou HTML. É fácil criar um ESCAPE CHARACTER que tenha uma chance de zero ou quase zero de existir no texto original.
Dados de exemplo com seqüências de escape
Esta é a história de um homem. >>>> (#) Por que essa história sobre um homem não é uma mulher? (#) ( ) Userid :: 77367 ( ) Comentário do gerente ( ) DataID :: 234234234 >>>> Um homem que foi cortar a grama, foi cortar a grama. O homem foi com o cachorro >>>> (#) Pergunte ao cliente se a história seria melhor com um gato (#) >>>> para cortar a grama. Então agora esta é a história de um homem e seu cachorro que foram cortar a grama.
Um homem e seu cachorro, foram cortar a grama, foram cortar a grama, um prado chegou sobre a montanha. >>>> (#) Isso soa muito melhor com uma floresta (**) Nota de sugestão (#) >>>>
O homem e seu cachorro e sua missão: cortar uma campina, uma campina alcançada sobre a montanha só é alcançada ao atravessar o rio.
Dados de exemplo sem seqüências de escape
Esta é a história de um homem. Um homem que foi cortar a grama, foi cortar a grama. O homem foi com o cachorro cortar a grama. Então agora esta é a história de um homem e seu cachorro que foram cortar a grama.
Um homem e seu cachorro, foram cortar a grama, foram cortar a grama, um prado chegou sobre a montanha.
O homem e seu cachorro e sua missão: cortar uma campina, uma campina alcançada sobre a montanha só é alcançada ao atravessar o rio.
Obviamente, isso é facilmente analisado, não é complexo como uma linguagem de marcação completa e é facilmente adaptável ao seu objetivo.
Resolvido ainda? Bem, eu diria que não. Nossa solução ainda tem alguns buracos. A indexação e o acesso estruturado desses dados são ruins. Além disso, não seria razoável consultar este arquivo (ou vários arquivos) ao mesmo tempo que editá-lo.
Como poderíamos resolver esse problema?
Eu sugeriria uma TABELA DE ALOCAÇÃO DE DADOS como um cabeçalho do documento. Eu também sugeriria implementar uma fila de atualização de tabela transacional . Deixe-me explicar. Os projetistas de um sistema de arquivos, particularmente um sistema de arquivos em disco rotativo, enfrentaram desafios de design semelhantes aos descritos acima. Eles precisavam incorporar informações sobre os arquivos no disco, juntamente com os dados. Uma ótima solução para a integridade do relacionamento desses dados foi duplicá- los em uma tabela de alocação de arquivos (FAT).
Isso significa que, para cada item de metadados individual, há uma entrada correspondente na tabela de alocação de dados . Portanto, é rápido, estruturado e relacional, e independente dos dados originais. Se forem necessárias consultas, junções ou atualizações nos metadados, isso será feito facilmente, basta acessar a Tabela de Alocação de Dados .
Obviamente, deve-se tomar cuidado para garantir que os metadados in-line originais sejam um reflexo real dos dados da Tabela de Alocação de Dados. É aí que entra a Fila de atualização da tabela transacional. Toda alteração, adição ou remoção de metadados é feita não nos próprios dados, mas na fila. a fila garantirá que todas as alterações sejam feitas nos dados em linha e na tabela ou que nenhuma alteração seja feita. Ele também permite que atualizações assíncronas sejam executadas, por exemplo, todos os metadados de um determinado usuário podem ser excluídos executando um comando de exclusão na fila. Se os metadados embutidos estivessem bloqueados e em uso, a fila não executaria nenhuma alteração até poder fazê-lo nos dados da Tabela e nos dados embutidos.
fonte
>>>>>(#1) Lorem ipsum (#1)>>>>>>
. Além disso, parece que sua abordagem nos comentários intext os vincularia a uma determinada posição fixa. Como isso funcionaria se o deslocamento fosse movido?Esse é um tipo típico de questão de engenharia, em que todas as suas opções têm trocas diferentes e qual é a melhor depende do que é importante para você. Infelizmente, você não forneceu informações suficientes para fazer a determinação.
Você também não parece considerar um problema semântico importante. Digamos que o texto original seja
Alguém adiciona um comentário em torno de "Bob" dizendo
Em seguida, o texto original é editado para
Você pode entender esse caso em particular usando um algoritmo de correspondência de texto, como o que é usado para mostrar um arquivo diff, mas as compensações de caracteres farão com que os metadados sejam anexados ao "Jan" em "Jane".
Pior é se o texto for editado para
Você pode descobrir como anexar os metadados a "Steve", mas como você sabe se eles se aplicam?
Além disso, você decidiu se os próprios metadados podem ter metadados? Isso pode mudar sua implementação.
Além das questões semânticas, não está muito claro o que você está fazendo com os dados. Eu pensei que talvez fosse muito inconveniente ter o texto original "poluído" com qualquer marcação, mas você estava certo em ter valores de identificação. O que não faz muito sentido se os metadados se aplicarem a uma seção de texto em vez de serem inseridos em um ponto no texto.
Meu palpite é que, para a maioria das finalidades, armazenar texto marcado é mais fácil, ou, segunda opção, passar para todo o SQL e ter o texto e a marcação representados por uma hierarquia de nós - basicamente um DOM em forma de tabela. Se seus dados são hierárquicos, pode ser mais fácil usar XML e obter analisadores existentes gratuitamente, em vez de escrever seus próprios.
É bem possível que exista alguma solução bastante simples que seja boa o suficiente para a sua situação exata, mas não posso lhe dizer o que é isso, porque realmente depende exatamente do que você está tentando fazer, em detalhes.
Eu sugiro fortemente que você encapsule qualquer estratégia que escolher, tanto quanto possível, embora isso seja bastante difícil de fazer se grande parte da sua implementação precisar estar visível para muitas consultas SQL.
Lamento que a resposta seja tão dispersa e cheia de "depende", mas as questões de design do mundo real são assim.
fonte
Eu acho que a sugestão do respondente anterior, a que você menciona na sua pergunta) é muito boa.
Ele se comportaria da mesma maneira que postamos links nos sites StackExchange, mas os dados de informações estariam em outra tabela. Os benefícios são: você tem os dados separados e, portanto, podem ser consultados e indexados. Na edição do texto, você pode verificar os IDs de metadados excluídos e limpar a tabela de metadados.
O único pequeno problema como você disse é a análise, mas você pode lidar com isso facilmente.
fonte
Digamos que eu tenho um texto:
Eu adiciono a nota assim:
[@123,#456,2w]
significa: user_id = 123, note_id = 456, e o texto marcado por esta nota se estende pelas próximas 2 palavras (podem ser caracteres (c
), frases (s
), parágrafos (p
) ou qualquer outra coisa). A sintaxe exata pode ser diferente, é claro.Nos editores de texto sem formatação, o texto das notas pode ser facilmente armazenado no final do documento, assim como nas notas de rodapé do Markdown.
Nos editores de rich text, esse tipo de nota pode ser exibido no texto como um ícone, e o texto marcado pode ser destacado de alguma forma. O usuário pode excluir essas notas da mesma forma que os caracteres normais com DelouBackspace editá-las com algum tipo de modo de edição especial. Eu imagino redimensionar áreas anotadas com um mouse e editar o texto da nota com a janela pop-up.
Prós:
Contras para edição de texto sem formatação:
Contras gerais:
fonte
nonummy
enibh
, ela não estragaria minhas compensações?