Zajmuję się tworzeniem aplikacji, która będzie musiała przechowywać wbudowane , intekstowe metadane. Rozumiem przez to: powiedzmy, że mamy długi tekst i chcemy przechowywać metadane związane z konkretnym słowem lub zdaniem tekstu.
Jaki byłby najlepszy sposób przechowywania tych informacji?
Moją pierwszą myślą było zawarcie w tekście jakiejś Markdown
składni , która następnie byłaby analizowana podczas pobierania. Coś wygląda tak:
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.
Wprowadziłoby to dwa problemy, o których mogę myśleć:
- Stosunkowo niewielki jest fakt, że jeśli wspomniana składnia przypadkowo znajdzie się na tym tekście, może to zepsuć się podczas analizowania.
- Najważniejsze jest to, że nie utrzymują one tych metadanych oddzielnie od samego tekstu.
Chciałbym mieć dyskretną strukturę danych do przechowywania tych danych, taką inną tabelę DB, w której przechowywane są te metadaty, aby móc ich używać w dyskretny sposób: zapytania, statystyki, sortowanie i tak dalej.
EDYCJA: Ponieważ osoba odpowiadająca usunęła odpowiedź, myślę, że dobrze byłoby dodać tutaj swoją sugestię, ponieważ była to praktyczna sugestia, która rozszerzyła się na tę pierwszą koncepcję. Plakat sugeruje użycie podobnej składni, ale połączenie metadanych PRIMARY KEY
z metadata
tabelą bazy danych.
Coś, co wyglądałoby tak:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit,
sed diam __nonummy nibh__[15432]
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Gdzie 15432
byłby ID
wiersz tabeli zawierający niezbędne, dostępne do zapytania informacje, jak na przykład poniżej.
Moją drugą myślą było przechowywanie tego rodzaju informacji w tabeli DB wyglądającej tak:
TABLE: metadata
ID TEXT_ID TYPE OFFSET_START OFFSET_END CONTENT
1 lipsum note 68 79 this sounds really funny latin
W ten sposób metadane miałyby unikalny identyfikator, text_id
jako klucz obcy podłączony do tabeli przechowującej teksty i łączyłby dane z samym tekstem za pomocą prostego zakresu przesunięcia znaków .
To by załatwiło sprawę, oddzielając dane od metadanych , ale problem, który od razu widzę dzięki temu podejściu, polega na tym, że tekst zasadniczo nie byłby edytowalny . Lub, gdybym chciał zaimplementować edycję tekstu po przypisaniu metadanych, musiałbym w zasadzie obliczyć dodawanie lub usuwanie znaków w porównaniu z poprzednią wersją i sprawdzanie, czy każda z tych modyfikacji dodaje lub usuwa znaki przed lub po każdym powiązanych metadanych.
Co dla mnie brzmi jak bardzo nieeleganckie podejście.
Czy masz jakieś wskazówki lub sugestie dotyczące sposobu rozwiązania problemu?
Edycja 2: niektóre problemy XML
Dodając kolejny przypadek, który byłby niezbędny do tego rozdzielenia danych i metadanych.
- Powiedzmy, że chcę umożliwić różnym użytkownikom posiadanie różnych zestawów metadanych tego samego tekstu , z możliwością lub bez możliwości wyświetlania przez każdego użytkownika metadanych innego użytkownika.
Każde rozwiązanie z wyprzedaży rodzaju (lub HTML lub XML) byłoby trudne do zrealizowania w tym momencie. Jedynym rozwiązaniem w tym przypadku, o którym mogłem pomyśleć, byłoby posiadanie kolejnej tabeli DB, która zawierałaby wersję oryginalnego tekstu dla jednego użytkownika, łączącą się z oryginalną tabelą tekstową za pomocą a FOREIGN KEY
.
Nie jestem pewien, czy to też jest bardzo eleganckie.
- XML ma hierarchiczny model danych: każdy element, który znajduje się w granicach innego elementu, jest uważany za jego element podrzędny , co najczęściej nie występuje w modelu danych, którego szukam; w XML dowolny dzieci element musi być zamknięte przed rodzicem tag może być zamknięty, dzięki czemu bez nakładania się elementów.
Przykład:
<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>
Tutaj mamy dwa różne problemy:
Nakładające się różne elementy: Pierwszy komentarz zaczyna się w obrębie pierwszej nuty, ale kończy się po zakończeniu pierwszej nuty, tzn. Nie jest to jej potomek.
Nakładające się te same elementy: ostatnia nuta i pogrubiona nuta nakładają się; jednak ponieważ są one tego samego rodzaju elementem, analizator składni zamknąłby ostatnio otwarty element przy pierwszym zamknięciu, a pierwszy otwarty element przy ostatnim zamknięciu, co w tych okolicznościach nie jest zamierzone.
źródło
Odpowiedzi:
Wybrałbym mieszankę twoich rozwiązań, ale zamiast tego użyłbym standardu: XML. Miałbyś taką składnię jak ta
Dlaczego XML
Jeśli się nad tym zastanowić, to dokładnie tak zbudowana jest cała sieć : treść (rzeczywisty tekst), która przenosi semantyczne - tak zwane metadane - za pomocą znaczników HTML.
W ten sposób masz naprawdę fajny świat, który się otwiera:
Lorem <note>ipsum</note>
pojawia sięlorem ips*
na przykład podczas wyszukiwania .Dlaczego XML zamiast Markdown
Strona internetowa, taka jak stackexchange, wykorzystuje markdown, ponieważ semantyka, którą przekazuje treść, jest dość prosta: wyróżnienie, linki / adresy URL, obraz, nagłówek itp. Wygląda na to, że semantyczność dodajesz do treści
Dlatego wyczuwam, że Markdown nie byłby naprawdę dobrym pomysłem. Również Markdown naprawdę nie jest znormalizowany, a parsowania / dumping może być ból w dupie, nawet bardziej markdownish składnia zobaczyć posta Jeff Atwood za około WTF poznał na parsowania Markdown .
O rozdzieleniu danych i metadanych
Takie oddzielenie nie jest obowiązkowe. Zakładam, że szukasz korzyści, jakie daje:
Wszystkie te obawy zostały wyjaśnione przy użyciu XML. Z pliku XML można łatwo zrzucić dowolną treść pozbawioną znaczników, a dane / metadane są oddzielone, podobnie jak atrybut i rzeczywisty tekst są oddzielone w XML.
Nie sądzę też, żebyś naprawdę mógł mieć swoje metadane całkowicie niezwiązane z danymi . Z tego, co opisujesz, twoje metadane są kompozycją twoich danych, tzn. Usunięcie danych prowadzi do usunięcia metadanych. To tutaj metadane odbiegają od zwykłego HTML / CSS. CSS nie znika po usunięciu elementu HTML, ponieważ można go zastosować do innych elementów. Nie sądzę, że tak jest w przypadku twoich metadanych.
Posiadanie metadanych blisko danych, takich jak XML lub Markdown, pozwala na łatwe zrozumienie (i być może debugowanie) danych. Również przykład, który podajesz w drugiej myśli, dodaje pewnej złożoności, ponieważ dla każdego czytanego przeze mnie danych muszę wykonać zapytanie do tabeli metadanych, aby je uzyskać. Jeśli relacja między twoimi danymi a metadanymi wynosi 1: 1 lub 1: N, to jest to IMO wyraźnie bezużyteczne i przynosi jedynie złożoność (dobry przypadek YAGNI).
źródło
Przypadek użycia rozwiązania
Nie zgadzam się z niektórymi innymi odpowiedziami, po prostu dlatego, że chociaż świetne rozwiązania, prawdopodobnie nie są twoim rozwiązaniem. Tak XML ma skrót znaczników w akronimie, ale prawdopodobnie nie jest idealny dla twojej sytuacji. Jest zbyt skomplikowany, nie zapewnia dużej pomocy w oddzieleniu metadanych od oryginalnego tekstu. Zasadniczo zmieni wszystko w formę metadanych, tworząc jeden zestaw danych z nadwagą.
Ponieważ prawdopodobnie nie ma absolutnie poprawnego rozwiązania lub podejścia, najlepsze rozwiązanie odpowiada na pytanie:
Ponadto, jeśli spróbujesz zapytać, w jaki sposób projekt rozwiązania może z natury zwiększyć wartość systemu w sposób, w jaki będzie on używany, to jesteś bliżej znalezienia swojej eleganckiej odpowiedzi.
Zrozumienie problemu
Ok, dość komentarza, zagłębmy się w problem. To jest taki problem, jaki rozumiem (oczywiście dodanie do niego będzie korzystne):
Budowanie projektu rozwiązania
Rozumiejąc problem tak, jak go nakreśliłem powyżej, zacznę teraz sugerować możliwe rozwiązania i podejścia, które mają na celu rozwiązanie powyższego problemu.
składniki
Widzę więc, że musiałby istnieć niestandardowy system dostępu użytkowników. Odfiltrowałby odpowiednie i nieistotne metadane z oryginalnego tekstu. Ułatwiłoby to edycję i przeglądanie metadanych w tekście. Zapewniłoby to integralność relacji między metadanymi a oryginalnym tekstem. Ustrukturyzuje metadane i zaoferuje źródło danych dla relacyjnego systemu danych. Najprawdopodobniej zapewni wiele innych funkcji zależnych od celu.
Struktura
Ponieważ ważne jest zachowanie integralności metadanych z oryginalnym tekstem, najlepszym sposobem zapewnienia tego jest utrzymanie metadanych zgodnych z oryginalnym tekstem. Zapewni to korzyść polegającą na pewnej edycji oryginalnych danych bez naruszania tej integralności.
Obawy związane z tym podejściem polegają na uszkodzeniu metadanych przez oryginalne dane i odwrotnie. Odpowiednie indeksowanie i struktura metadanych i ich (meta) metadanych w sposób umożliwiający zapytania i aktualizacje oraz efektywny dostęp. Łatwe filtrowanie metadanych z oryginalnego tekstu.
Mając to na uwadze, sugerowałbym, aby część rozwiązania opierała się na podejściu polegającym na używaniu ZNAKÓW UCIECZKI w oryginalnym tekście. To nie jest to samo, co projektowanie własnego języka znaczników lub używanie istniejącego języka znaczników, takiego jak XML lub HTML. Łatwo jest zaprojektować ZNAK UCIECZKI, który ma zerową lub prawie zerową szansę na istnienie w oryginalnym tekście.
Przykładowe dane z sekwencjami ucieczki
To jest historia mężczyzny. >>>> (#) Dlaczego ta historia o mężczyźnie nie jest kobietą? (#) ( ) Identyfikator użytkownika :: 77367 ( ) Komentarz menedżera ( ) DataID :: 234234234 >>>> Mężczyzna, który poszedł kosić łąkę, poszedł kosić łąkę. Mężczyzna poszedł ze swoim psem >>>> (#) Zapytaj klienta, czy zamiast tego lepiej byłoby z kotem (#) >>>> kosić łąkę. Więc teraz jest to historia mężczyzny i jego psa, którzy poszli kosić łąkę.
Jeden człowiek i jego pies poszli kosić łąkę, poszli kosić łąkę, łąkę sięgającą góry. >>>> (#) To brzmi znacznie lepiej w lesie (**) Wskazówka do sugestii (#) >>>>
Człowiek i jego pies i jego misja, aby kosić łąkę, łąka osiągnięta nad górą jest osiągana tylko podczas przekraczania rzeki.
Przykładowe dane bez sekwencji specjalnych
To jest historia mężczyzny. Mężczyzna, który poszedł kosić łąkę, poszedł kosić łąkę. Mężczyzna poszedł ze swoim psem kosić łąkę. Więc teraz jest to historia mężczyzny i jego psa, którzy poszli kosić łąkę.
Jeden człowiek i jego pies poszli kosić łąkę, poszli kosić łąkę, łąkę sięgającą góry.
Człowiek i jego pies i jego misja, aby kosić łąkę, łąka osiągnięta nad górą jest osiągana tylko podczas przekraczania rzeki.
Oczywiście jest to łatwe do przeanalizowania, nie jest skomplikowane jako cały język Mark-up i łatwo dostosowuje się do twojego celu.
Jeszcze rozwiązany? Powiedziałbym „nie”. Nasze rozwiązanie wciąż ma pewne dziury. Indeksowanie i uporządkowany dostęp do tych danych jest słaby. Nie byłoby również rozsądne zapytanie tego pliku (lub kilku plików) w tym samym czasie, co jego edycja.
Jak moglibyśmy rozwiązać ten problem?
Sugerowałbym TABELĘ ALOKACJI DANYCH jako nagłówek dokumentu. Proponuję również wdrożenie KOLEJNOŚCI AKTUALIZACJI TABELI AKTUALIZACJI . Pozwól mi wyjaśnić. Projektanci systemu plików, zwłaszcza systemu plików z dyskiem obrotowym, stanęli przed podobnymi wyzwaniami projektowymi, jak te opisane powyżej. Musieli osadzić informacje o plikach na dysku wraz z danymi. Świetnym rozwiązaniem dla integralności relacji tych danych było DUPLIKOWANIE ich w tabeli alokacji plików (FAT).
Oznacza to, że dla każdego pojedynczego elementu metadanych istnieje odpowiedni wpis w tabeli alokacji danych . Jest więc szybki, ustrukturyzowany i relacyjny oraz niezależny od oryginalnych danych. Jeśli na metadanych należy wykonać zapytania, łączenia lub aktualizacje, można to łatwo zrobić, po prostu uzyskując dostęp do tabeli alokacji danych .
Oczywiście należy zadbać o to, aby oryginalne metadane w wierszu były prawdziwym odzwierciedleniem danych tabeli alokacji danych. W tym momencie pojawia się kolejka aktualizacji tabeli transakcyjnej. Każda zmiana, dodanie lub usunięcie metadanych nie jest dokonywane w samych danych, ale w kolejce. kolejka upewni się, że albo wszystkie zmiany zostaną wprowadzone zarówno w danych w wierszu, jak i w tabeli, lub w ogóle nie zostaną wprowadzone żadne zmiany. Pozwala również na wykonywanie aktualizacji asynchronicznych, na przykład wszystkie metadane określonego użytkownika można usunąć, uruchamiając komendę delete w kolejce. Jeśli wbudowane metadane były zablokowane i używane, kolejka nie wprowadzałaby żadnych zmian, dopóki nie będzie w stanie dokonać zarówno danych tabeli, jak i danych wbudowanych.
źródło
>>>>>(#1) Lorem ipsum (#1)>>>>>>
. Wygląda również na to, że twoje podejście w komentarzach intekstowych wiązałoby je z pewną ustaloną pozycją. Jak by to działało, gdyby przesunięto przesunięcie?Jest to typowe pytanie inżynierskie, ponieważ wszystkie opcje mają różne kompromisy, a najlepsze z nich zależy od tego, co jest dla Ciebie ważne. Niestety nie podałeś wystarczających informacji, aby dokonać ustalenia.
Wydaje się również, że nie rozważasz ważnego problemu semantycznego. Powiedzmy, że oryginalny tekst to
Ktoś dodaje komentarz do powieści „Bob”
Następnie oryginalny tekst jest edytowany do
Państwo może wprowadzić pewne poczucie tym konkretnym przypadku z wykorzystaniem algorytmu dopasowania tekstu, takich jak to, co służy do wyświetlania plik diff, ale przesunięcia znaków zamierzamy uczynić metadanych dołączyć do „Jan” w „Jane”.
Gorzej jest, jeśli tekst jest edytowany do
Mógłbyś wymyślić, jak dołączyć metadane do „Steve'a”, ale skąd wiesz, czy ma to zastosowanie?
Czy również zdecydowałeś, czy same metadane mogą zawierać metadane? To może zmienić twoją implementację.
Poza kwestiami semantycznymi nie jest jasne, co robisz z danymi. Pomyślałem, że być może bardzo niewygodne było „zanieczyszczenie” oryginalnego tekstu dowolnym znacznikiem, ale wtedy w pewnym sensie nie przeszkadzało ci posiadanie wartości identyfikatora. Co nie ma większego sensu, jeśli metadane dotyczą odcinka tekstu zamiast wstawiania go do punktu w tekście.
Domyślam się, że dla większości celów przechowywanie zaznaczonego tekstu jest łatwiejsze, lub, po drugie, przejście całego SQL i posiadanie tekstu i znaczników reprezentowanych przez hierarchię węzłów - w zasadzie DOM w formie tabeli. Jeśli Twoje dane są zhierarchizowane, łatwiej jest użyć XML i uzyskać istniejące parsery za darmo, niż pisać własne.
Jest całkiem możliwe, że istnieje dość proste rozwiązanie, które jest wystarczająco dobre dla twojej konkretnej sytuacji, ale nie mogę ci powiedzieć, co to jest, ponieważ tak naprawdę zależy to od tego, co próbujesz zrobić, szczegółowo.
Zdecydowanie sugeruję, byś zawarł jak najwięcej strategii, którą wybierzesz, jak to tylko możliwe, choć jest to dość trudne, jeśli duża część twojej implementacji musi być widoczna dla wielu zapytań SQL.
Przepraszam, że odpowiedź jest tak rozproszona i pełna „to zależy”, ale takie pytania projektowe są w rzeczywistości.
źródło
Myślę, że sugestia poprzedniego odpowiedzi, którą wspominasz na swoje pytanie) jest bardzo dobra.
Zachowałoby się tak samo, jak publikujemy linki w witrynach StackExchange, ale dane informacyjne byłyby w innej tabeli. Zaletą jest to, że dane są rozdzielone, dlatego można je wyszukiwać i indeksować. Podczas edycji tekstu możesz sprawdzić usunięte identyfikatory metadanych i wyczyścić tabelę metadanych.
Jedynym małym problemem, jak powiedziałeś, jest parsowanie, ale możesz sobie z tym poradzić dość łatwo.
źródło
Powiedzmy, że mam tekst:
Dodaję notatkę w ten sposób:
[@123,#456,2w]
oznacza: user_id = 123, note_id = 456, a tekst oznaczony tą notatką obejmuje kolejne 2 słowa (mogą to być znaki (c
), zdania (s
), paragraps (p
) lub cokolwiek innego). Dokładna składnia może być oczywiście inna.W edytorach zwykłego tekstu tekst notatek można łatwo przechowywać na końcu dokumentu, podobnie jak w przypadku przypisów Markdown.
W edytorach tekstu sformatowanego tego rodzaju notatkę można wyświetlić w tekście jako ikonę, a zaznaczony tekst można w pewien sposób podświetlić. Użytkownik może następnie usunąć takie notatki tak jak zwykłe znaki za pomocą Dellub Backspacei edytować je za pomocą specjalnego trybu edycji. Wyobrażam sobie zmianę rozmiaru zaznaczonych obszarów za pomocą myszy i edytowanie tekstu notatki z wyskakującym oknem.
Plusy:
Wady edycji zwykłego tekstu:
Ogólne wady:
źródło
nonummy
inibh
, czy nie zepsułoby to moich przesunięć?