Je développe une application qui devra stocker des métadonnées intext et intext . Ce que je veux dire par là est le suivant: disons que nous avons un long texte et que nous voulons stocker des métadonnées liées à un mot ou une phrase spécifique du texte.
Quelle serait la meilleure façon de stocker ces informations?
Ma première pensée a été d'inclure dans le texte une sorte de Markdown
syntaxe qui serait ensuite analysée lors de la récupération. Quelque chose ressemblant à ceci:
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.
Cela introduirait deux problèmes auxquels je peux penser:
- Une relativement petite, est que si ladite syntaxe se trouve fortuitement sur ledit texte, elle peut perturber l'analyse.
- Le plus important est que cela ne maintient pas ces métadonnées distinctes du texte lui-même.
J'aimerais avoir une structure de données discrète pour contenir ces données, une table de base de données différente dans laquelle ces métadonnées sont stockées, afin de pouvoir les utiliser de manière discrète: interrogation, statistiques, tri, etc.
EDIT: Étant donné que le répondeur a supprimé sa réponse, je pense qu'il pourrait être bon d'ajouter sa suggestion ici, car il s'agissait d'une suggestion réalisable qui a développé ce premier concept. L'affiche a suggéré d'utiliser une syntaxe similaire, mais de lier les métadonnées à la table PRIMARY KEY
de la metadata
base de données.
Quelque chose qui ressemblerait à ceci:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit,
sed diam __nonummy nibh__[15432]
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Où 15432
serait la ligne ID
d'une table contenant les informations nécessaires et interrogeables, comme dans l'exemple ci-dessous.
Ma deuxième pensée a été de stocker des informations de ce type dans une table DB ressemblant à ceci:
TABLE: metadata
ID TEXT_ID TYPE OFFSET_START OFFSET_END CONTENT
1 lipsum note 68 79 this sounds really funny latin
De cette façon, les métadonnées auraient un identifiant unique, a en text_id
tant que clé étrangère connectée à la table stockant les textes et elles relieraient les données au texte lui-même en utilisant une plage de décalage de caractères simple .
Cela ferait l'affaire de garder les données séparées des métadonnées , mais un problème que je peux immédiatement voir avec cette approche est que le texte ne serait fondamentalement pas modifiable . Ou, si je voulais implémenter l'édition du texte après l'attribution des métadonnées, je devrais essentiellement calculer les ajouts de caractères, ou la suppression par rapport à la version précédente, et vérifier si chacune de ces modifications ajoute ou supprime des caractères avant ou après chaque des métadonnées associées.
Ce qui, pour moi, ressemble à une approche vraiment non élégante.
Avez-vous des conseils ou des suggestions sur la façon dont je pourrais aborder le problème?
Edit 2: quelques problèmes XML
Ajout d'un autre cas qui rendrait tout à fait nécessaire cette séparation des données et des métadonnées.
- Disons que je veux permettre à différents utilisateurs d'avoir différents jeux de métadonnées du même texte , avec ou sans la possibilité pour chaque utilisateur d'afficher réellement les autres métadonnées utilisateur.
Toute solution du type démarquage (ou HTML ou XML) serait difficile à mettre en œuvre à ce stade. La seule solution dans ce cas à laquelle je pourrais penser serait d'avoir encore une autre table DB qui contiendrait la version mono-utilisateur du texte d'origine, se connectant à la table de texte d'origine en utilisant a FOREIGN KEY
.
Je ne sais pas si c'est très élégant non plus.
- XML a un modèle de données hiérarchique: tout élément qui se trouve à l' intérieur des frontières d'un autre élément est considéré comme son enfant , ce qui n'est généralement pas le cas dans le modèle de données que je recherche; en XML, tout élément enfant doit être fermé avant de pouvoir fermer la balise parent , ce qui ne permet aucun chevauchement d'éléments.
Exemple:
<note content="the beginning of the famous placeholder">
Lorem ipsum dolor sit<comment content="I like the sound of amet/elit">
amet</note>
, elect adipiscing consectetuer</comment>
,<note content="adversative?">
sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.<note content="funny latin">
</note>
</note>
Ici, nous avons deux problèmes différents:
Différents éléments qui se chevauchent: Le premier commentaire commence dans la première note, mais se termine après la fin de la première note, c'est-à-dire que ce n'est pas son enfant.
Mêmes éléments qui se chevauchent: La dernière note et la note en gras se chevauchent; cependant, comme il s'agit du même type d'élément, l'analyseur fermerait le dernier élément ouvert à la première fermeture et le premier élément ouvert à la dernière fermeture, ce qui, dans ce cas, n'est pas ce à quoi il est destiné.
la source
Réponses:
J'irais pour un mélange de vos solutions, mais à la place, j'utiliserais un standard: XML. Vous auriez une syntaxe comme celle-ci
Pourquoi XML
Si vous y réfléchissez, c'est exactement la façon dont tout le Web est structuré : le contenu (texte réel) qui porte la sémantique - ce que vous appelez des métadonnées - via des balises html.
De cette façon, vous avez un monde vraiment cool qui s'ouvre:
Lorem <note>ipsum</note>
est soulevé lorsque vous recherchezlorem ips*
par exemple.Pourquoi XML sur Markdown
Un site Web comme stackexchange utilise le démarquage car la sémantique véhiculée par son contenu est plutôt basique: accentuation, liens / URL, image, en-tête, etc. Il semble que la sémantique que vous ajoutez à votre contenu soit
Ainsi, je sens que Markdown ne serait pas une très bonne idée. De plus, Markdown n'est pas vraiment standardisé, et analyser / vider cela pourrait être une douleur dans le cul, encore plus une syntaxe de démarque voir le post de Jeff Atwood sur le WTF qu'il a rencontré lors de l'analyse de Markdown .
Sur la séparation entre les données et les métadonnées
En soi, une telle séparation n'est pas obligatoire. Je suppose que vous recherchez l'avantage qu'il apporte:
Toutes ces préoccupations sont résolues par l'utilisation de XML. À partir du XML, vous pouvez facilement vider tout contenu supprimé par balise, et les données / métadonnées sont séparées, tout comme l'attribut et le texte réel sont séparés en XML.
De plus, je ne pense pas que vous puissiez vraiment avoir vos métadonnées totalement liées à vos données . D'après ce que vous décrivez, vos métadonnées sont une composition de vos données, c'est-à-dire que la suppression des données entraîne la suppression des métadonnées. C'est là que vos métadonnées divergent du HTML / CSS habituel. CSS ne disparaît pas lorsqu'un élément html est supprimé, car il peut être appliqué à d'autres éléments. Je ne pense pas que ce soit le cas dans vos métadonnées.
Le fait d'avoir des métadonnées proches des données, comme dans XML ou Markdown, permet une compréhension facile (et peut-être un débogage) des données. De plus, l'exemple que vous donnez sur votre deuxième réflexion ajoute de la complexité, car pour chaque donnée que je lis, je dois interroger la table de métadonnées pour les obtenir. Si la relation entre vos données et vos métadonnées est de 1: 1 ou 1: N, alors c'est l'OMI clairement inutile et ne fait qu'apporter de la complexité (un bon cas de YAGNI).
la source
Le cas d'utilisation de la solution
Je ne suis pas d'accord avec certaines des autres réponses, tout simplement parce que, bien que d'excellentes solutions, elles ne sont probablement pas votre solution. Oui, XML a le mot balisage dans son acronyme, mais ce n'est probablement pas idéal pour votre situation. C'est beaucoup trop complexe, il offre peu d'aide pour séparer les métadonnées du texte d'origine. Essentiellement, cela transformera tout en une forme de métadonnées, créant un ensemble de données en surpoids.
Puisqu'il n'y a probablement pas de solution ou d'approche absolument correcte, la meilleure solution répond à la question:
De plus, si vous essayez de demander, comment une conception de solution pourrait intrinsèquement ajouter à la valeur du système, de la manière dont elle sera utilisée, alors vous êtes plus près de trouver votre réponse élégante .
Comprendre le problème
Ok assez de commentaires, creusons le problème. C'est le problème tel que je le comprends (évidemment y ajouter sera bénéfique):
Construire la conception de la solution
Comprenant le problème tel que je l'ai décrit ci-dessus, je vais maintenant commencer à suggérer des solutions et des approches possibles qui visent à résoudre le problème ci-dessus.
Composants
Je verrais donc qu'il faudrait un système d'accès utilisateur personnalisé. Il filtrerait les métadonnées pertinentes et non pertinentes du texte d'origine. Cela faciliterait l'édition et la visualisation des métadonnées dans le texte. Cela garantirait l'intégrité de la relation entre les métadonnées et son texte d'origine. Il structurerait les métadonnées et offrirait une source de données à un système de données relationnelles. Il fournira très probablement une multitude d'autres fonctions spécifiques.
Structure
Donc, comme il est important de conserver l'intégrité des métadonnées par rapport au texte d'origine, la meilleure façon de garantir cela est de maintenir les métadonnées en ligne avec le texte d'origine. Cela offrira l'avantage que les données originales peuvent être modifiées en toute confiance sans briser cette intégrité.
Les préoccupations avec cette approche sont la corruption des métadonnées par les données originales et vice versa. L'indexation et la structuration adéquates des métadonnées et de ses (méta) métadonnées d'une manière qui permet des requêtes et des mises à jour et un accès efficace. Le filtrage facile des métadonnées à partir du texte d'origine.
Dans cette optique, je suggère qu'une partie de la solution soit basée sur l'approche de l'utilisation des CARACTÈRES D'ÉVACUATION dans le texte d'origine. Ce n'est pas la même chose que de concevoir votre propre langage de balisage ou d'utiliser un langage de balisage existant tel que XML ou HTML. Il est facile de concevoir un CARACTÈRE D'ÉVACUATION qui a une chance nulle ou presque nulle d'exister dans le texte d'origine.
Exemples de données avec des séquences d'échappement
Ceci est l'histoire d'un homme. >>>> (#) Pourquoi cette histoire d'un homme n'est pas une femme? (#) ( ) Userid :: 77367 ( ) Commentaire du directeur ( ) DataID :: 234234234 >>>> Un homme qui est allé tondre un pré, est allé tondre un pré. L'homme est parti avec son chien >>>> (#) Demandez au client si l'histoire serait mieux avec un chat à la place (#) >>>> pour tondre le pré. Alors maintenant, c'est l'histoire d'un homme et de son chien qui est allé tondre un pré.
Un homme et son chien sont allés tondre un pré, sont allés tondre un pré, un pré atteint au-dessus de la montagne. >>>> (#) Cela sonne beaucoup mieux avec une forêt (**) Note de suggestion (#) >>>>
L'homme et son chien et sa mission, tondre un pré, un pré atteint au dessus de la montagne n'est atteint qu'en traversant la rivière.
Exemples de données sans séquences d'échappement
Ceci est l'histoire d'un homme. Un homme qui est allé tondre un pré est allé tondre un pré. L'homme est allé avec son chien pour tondre le pré. Alors maintenant, c'est l'histoire d'un homme et de son chien qui est allé tondre un pré.
Un homme et son chien sont allés tondre un pré, sont allés tondre un pré, un pré atteint au-dessus de la montagne.
L'homme et son chien et sa mission, tondre un pré, un pré atteint au dessus de la montagne n'est atteint qu'en traversant la rivière.
De toute évidence, cela est facilement analysé, pas complexe comme un langage de balisage complet et facilement adaptable à votre objectif.
Résolu encore? Eh bien, je dirais non. Notre solution a encore quelques trous. L'indexation et l'accès structuré de ces données sont médiocres. De plus, il ne serait pas raisonnable d'interroger ce fichier (ou plusieurs fichiers) en même temps que le modifier.
Comment pourrions-nous résoudre ce problème?
Je suggérerais un TABLEAU D'ALLOCATION DE DONNÉES comme en-tête de document. Je suggérerais également la mise en place d'une QUEUE DE MISE À JOUR DE TABLE TRANSACTIONNELLE . Laissez-moi expliquer. Les concepteurs d'un système de fichiers, en particulier d'un système de fichiers à disque rotatif, ont été confrontés à des défis de conception similaires à ceux que vous avez décrits ci-dessus. Ils devaient intégrer des informations sur les fichiers sur le disque avec, ainsi que les données. Une excellente solution pour l'intégrité des relations de ces données était de les dupliquer dans une table d'allocation de fichiers (FAT).
Cela signifie que pour chaque élément de métadonnées individuel, il existe une entrée correspondante dans le tableau de répartition des données . Il est donc rapide, structuré et relationnel, et indépendant des données d'origine. Si des requêtes, des jointures ou des mises à jour doivent être effectuées sur les métadonnées, cela se fait facilement en accédant simplement à la table d'allocation des données .
De toute évidence, il faut veiller à ce que les métadonnées en ligne d'origine reflètent bien les données de la table d'allocation des données. C'est là qu'intervient une file d'attente de mise à jour de table transactionnelle. Chaque modification, ajout ou suppression de métadonnées se fait non pas sur les données elles-mêmes, mais plutôt sur la file d'attente. la file d'attente s'assurera alors que toutes les modifications sont apportées aux données en ligne et de table, ou qu'aucune modification n'est apportée du tout. Il permet également d'effectuer des mises à jour asynchrones, par exemple, toutes les métadonnées d'un certain utilisateur peuvent être supprimées en exécutant une commande de suppression dans la file d'attente. Si les métadonnées en ligne étaient verrouillées et utilisées, la file d'attente n'effectuerait aucune modification tant qu'elle ne pourrait pas le faire à la fois aux données de la table et aux données en ligne.
la source
>>>>>(#1) Lorem ipsum (#1)>>>>>>
. En outre, il semble que votre approche dans les commentaires intext les oblige à se lier à une certaine position fixe, comment cela fonctionnerait-il si le décalage était déplacé?Il s'agit d'un type typique de question d'ingénierie dans la mesure où toutes vos options ont des compromis différents, et ce qui dépend le mieux de ce qui est important pour vous. Malheureusement, vous n'avez pas donné suffisamment d'informations pour prendre la décision.
Vous n'avez pas non plus semblé considérer un problème sémantique important. Disons que le texte d'origine est
Quelqu'un ajoute un commentaire autour de "Bob" en disant
Ensuite, le texte d'origine est modifié pour
Vous pourriez comprendre ce cas particulier en utilisant un algorithme de correspondance de texte tel que ce qui est utilisé pour afficher un fichier diff, mais les décalages de caractères vont rendre les métadonnées attachées au "Jan" dans "Jane".
Pire encore si le texte est modifié en
Vous pourriez réussir à comprendre comment attacher les métadonnées à "Steve", mais comment savoir si cela s'applique?
De plus, avez-vous décidé si les métadonnées elles-mêmes peuvent avoir des métadonnées? Cela pourrait changer votre implémentation.
Au-delà des problèmes sémantiques, ce que vous faites avec les données n'est pas très clair. Je pensais que c'était peut-être très gênant d'avoir le texte d'origine "pollué" avec n'importe quel balisage, mais alors vous étiez en quelque sorte OK avec des valeurs d'identification. Ce qui n'a pas beaucoup de sens si les métadonnées s'appliquent à une section de texte au lieu d'être insérées dans un point du texte.
Je suppose que, dans la plupart des cas, le stockage du texte balisé est plus facile, ou, deuxième choix, passer tout SQL et avoir le texte et le balisage représentés par une hiérarchie de nœuds - essentiellement un DOM sous forme de tableau. Si vos données sont hiérarchiques, il peut être plus facile d'utiliser XML et d'obtenir gratuitement les analyseurs existants, plutôt que d'écrire les vôtres.
Il est tout à fait possible qu'il existe une solution assez simple qui soit assez bonne pour votre situation exacte, mais je ne peux pas vous dire ce que c'est parce que cela dépend vraiment de ce que vous essayez de faire, en détail.
Je vous suggère fortement d'encapsuler autant que possible la stratégie que vous choisissez, bien que cela soit assez difficile à faire si une grande partie de votre implémentation doit être visible par de nombreuses requêtes SQL.
Désolé que la réponse soit si dispersée et si pleine de "ça dépend", mais les questions de conception du monde réel sont comme ça.
la source
Je pense que la suggestion du répondeur précédent, celle que vous mentionnez sur votre question) est très bonne.
Cela se comporterait de la même manière que nous publions des liens sur les sites StackExchange, mais les données d'informations seraient sur une autre table. Les avantages sont que vous avez les données séparées et donc interrogeables et indexables. Lors de la modification du texte, vous pouvez vérifier les ID de métadonnées supprimés et nettoyer la table de métadonnées.
Le seul petit problème comme vous l'avez dit est l'analyse, mais vous pouvez y faire face assez facilement.
la source
Disons que j'ai un texte:
J'ajoute la note comme ceci:
[@123,#456,2w]
signifie: user_id = 123, note_id = 456, et le texte marqué par cette note s'étend sur les 2 mots suivants (peut être des caractères (c
), phrases (s
), paragraps (p
) ou autre). La syntaxe exacte peut être différente, bien sûr.Dans les éditeurs de texte brut, le texte des notes peut être facilement stocké à la fin du document, tout comme avec les notes de bas de page Markdown.
Dans les éditeurs de texte enrichi, ce type de note peut être affiché dans le texte sous forme d'icône et le texte marqué peut être mis en surbrillance d'une manière ou d'une autre. L'utilisateur peut ensuite supprimer ces notes comme des caractères normaux avec Delou Backspace, et les modifier avec une sorte de mode d'édition spécial. J'imagine redimensionner les zones notées avec une souris et éditer le texte des notes avec une fenêtre contextuelle.
Avantages:
Inconvénients pour l'édition de texte brut:
Contre général:
la source
nonummy
etnibh
, cela ne gâcherait-il pas mes décalages?