Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
nutzergenerierte Text-Änderung (Edit-History / Archivierung)
Froschkoenig84
myCSharp.de - Member



Dabei seit:
Beiträge: 63
Herkunft: Scheibenwelt

Themenstarter:

nutzergenerierte Text-Änderung (Edit-History / Archivierung)

beantworten | zitieren | melden

Hallo.

Ich möchte gerne eine Art Blog bauen, bei dem es möglich ist, Nachrichten zu schreiben und auch zu kommentieren. Ähnlich wie es in den meisten Blogs oder auch bei Facebook in der Pinwall möglich ist, soll man seine Texte im Nachhinein noch ändern können.

Prinzipiell hätte ich einfach gesagt, dass man für jede Version einen eigenen Datensatz in die DB schreibt. Aber bei extrem langen Texten, nimmt das mit der Zeit auch einen relativ großen Umfang ein. Vor allem dann, wenn mehrmals nur einzelne Buchstaben/Rechtschreibfehler verändert worden oder ich irgendwann wirklich sehr viele, schreibwütige Nutzer zähle.


Jedesmal einen LongText in die DB zu hämmern, nur weil sich einzelne Zeichen verändert haben, erscheint mir als sparsamer DB-Entwickler etwas verschwenderisch. - Okay Speicherplatz ist natürlich nicht so wichtig/teuer, wie die Leistung des Servers, aber sooft wird die History einzelner Beiträge ja gar nicht angeschaut, es dient daher ehr einem Fallback-Zweck, bzw. der optionalen Möglichkeit, bei Interesse.

Ich bin ein GIT-Fan und würde gerne "nur" die Veränderungen zur aktuellen Version (also genau umgekehrt) wegspeichern. Es soll deswegen die "aktuelle" Version als Volltext weggespeichert werden, da diese Version am häufigsten aufgerufen wird und daher nicht erst dynamisch zusammegschustert werden sollte.

NEU...
Lorem ipsum dolor sit amet, [B][COLOR]consetetur[/COLOR][/B] sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.

Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. [B][COLOR]At vero eos et accusam et justo duo dolores et ea rebum.[/COLOR][/B]

Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

Nam liber tempor cum soluta nobis eleifend option congue [B][COLOR]nihil[/COLOR][/B] imperdiet doming id quod mazim placerat facer possim assum.

ALT...
Lorem ipsum dolor sit amet, [B][COLOR]consteteur[/COLOR][/B] sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.

Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. [B][COLOR]Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.[/COLOR][/B] 

Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

Nam liber tempor cum soluta nobis eleifend option congue [B][COLOR]nhiil[/COLOR][/B] imperdiet doming id quod mazim placerat facer possim assum.

Zunächst dachte ich an eine IndexOf()-Substring-Liste für die Änderungen. Aber ich habe auch nicht die Zeit, sämtliche Logik zu prüfen. Vermutlich gibt es zu diesem Thema bereits jede Menge fertige Skripte, Module oder Apps.


Ich kenne sie nur nicht.

Vielleicht hat ja jemand von euch bereits so etwas verwendet.
Wichtig ist noch, dass ich kein fertiges Blog-System verwende, sondern etwas eigenes entwickeln möchte.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Froschkoenig84 am .
private Nachricht | Beiträge des Benutzers
Taipi88
myCSharp.de - Member

Avatar #avatar-3220.jpg


Dabei seit:
Beiträge: 1.029
Herkunft: Mainz

beantworten | zitieren | melden

Hi,

um dir den richtigen Suchbegriff zu geben: Du suchst ein Diff-Tool.

Recht vielversprechend sieht folgendes aus:
https://github.com/mmanela/diffplex

LG
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5.655
Herkunft: Leipzig

beantworten | zitieren | melden

Hi Froschkoenig84
Zitat von Froschkoenig84
Zunächst dachte ich an eine IndexOf()-Substring-Liste für die Änderungen. Aber ich habe auch nicht die Zeit, sämtliche Logik zu prüfen.
Zitat von Froschkoenig84
Wichtig ist noch, dass ich kein fertiges Blog-System verwende, sondern etwas eigenes entwickeln möchte.

Widerspricht sich das nicht ein bißchen? Du hast zwar keine Zeit, die Logik für diese einzelne Funktion "zu prüfen" (was immer das bedeuten mag), aber du willst ALLES selbst umsetzen?
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15.832

beantworten | zitieren | melden

Ich kann mir nicht vorstellen, dass ihr irgendwas auf diesem Wege baut, das sich lohnt.
Vermutlich kostet das Ganze mehr Ressourcen unterm Strich.

Speicherplatz ist viel viel viel günstiger als CPU-Last, sodass sich der Diff niemals lohnen wird.
Davon abgesehen komprimieren Datenbanken Inhalte schon von Haus aus.
private Nachricht | Beiträge des Benutzers
Froschkoenig84
myCSharp.de - Member



Dabei seit:
Beiträge: 63
Herkunft: Scheibenwelt

Themenstarter:

beantworten | zitieren | melden

@Abt: Damit hatte ich fast gerechnet. Also dann dachte ich daran, es wirklich extrem einfach zu gestalten und einfach zwei DB-Felder (aktuelleVersion, jsonAlleAltenVersionen). Im ersten Feld steht wie weiterhin der aktuelle Text, in einer weiteren Spalte dann ein JSON der vergangenen Versionen. (*Kurze Info, es handelt sich um eine SPA, daher werden alle DB-Abfragen, auf Anforderung via JSON/AJAX-Response gesendet.

Danke an euch alle. - Dann spare ich mir da jegliche Diff-Tool-Entwicklung/-Einbindung.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15.832

beantworten | zitieren | melden

Also untypisiert ein Json schreiben ist natürlich... auch ned gerade das Wahre.
Erstell doch einfach eine zusätzliche Tabelle für den Verlauf; das ist ein Standard-Fall.
Genau so macht es das Forum hier übrigens auch.
private Nachricht | Beiträge des Benutzers
Froschkoenig84
myCSharp.de - Member



Dabei seit:
Beiträge: 63
Herkunft: Scheibenwelt

Themenstarter:

beantworten | zitieren | melden

@Abt:

Na ja, aber erstens ist es nicht untypisiert, da ich einfach ein DictObj mit entsprechenden Value-Typen dahinterlege (für PrimaryKey [= !TimeStamp/DateTime)] und Values [= !UserId, Message, ?Comments].

Zweitens bin ich mir noch nicht sicher, ob ich gleich BSON (MongoDB) schreibe, aktuell habe ich aber noch keinen eigenen Server und werde vermutlich aus Kostengründen zunächst auf PostGreSQL zurückgreifen, bevor ich mich entscheide, ob ich Trans-/MSSQL oder MongoDB nutze. Der Vorteil von PostGre ist, dass es sowohl JSON-Queries, als auch SQL-Queries unterstützt, auch wenn es vorwiegend relational aufgebaut ist.

Ich war früher nie ein Fan von NonSQL-DBs, aber ich nutze im Job inzwischen sehr gerne MongoDB und die Geschwindigkeit ist der Hammer, außerdem bekommt man mit vernünftigen Abfragen bereits das exakte Ziel-JSON für die API-Ausgabe, auch wenn ich es immer noch mal überprüfe. ;)

Ich habe mit OracleSQL angefangen, als ich Ende der 90er meine Ausbildung als Banksoftware-Entwickler begonnen hatte. Bin aber irgendwann zur Webentwicklung gekommen und habe auf PHP und MySQL umgeswiched, was auch lange sehr gut funktioniert hat. Dann habe ich irgendwann wieder mit C#.NET zu tun gehabt und natürlich auch mit MSSQL und war gerade im Bezug auf BigData sehr begeistert davon. Inzwischen bin ich an der Entwicklung mächtiger SPAs beteiligt und bin derzeit begeistert von MongoDB.

Aber privat hat mir jemand PostGre empfohlen, als Mix zwischen SQL und JSON. Anfangs hielt ich das für lächerlich, ... aber inzwischen bin ich überrascht, wie schnell eine gut konfigurierte und saubere PgDb läuft. Gerade wenn es um die Fütterung einer JSON-API geht. Du hast die Standardfilter für SQL-Queries um Relationen vernünftig über SQL-JOINs zu bedienen, dann aber wieder JSONs dahinter, die du mit JSON-Filtern noch detailliert steuern kannst. Die Ausgabe ist dann quasi schon das finale JSON, quasi ohne eine Zeile C#-Code. ;) Wobei ich via LINQ natürlich die RESTful-Controller (DataCtrl, UserCtrl) und somit auch die DB-Abfragen via C#.NET steuere. Trotzdem, PostGre ist ein toller Mix aus relationaler und non-relationaler DB. :)

Zurück zum Thema, hab auch über eine weitere Tabelle nachgedacht. Ist ja auch nicht kompliziert, daraus ein JSON für die Ausgabe zu konvertieren, aber irgendwie ein JSON und aufgrund weniger Tabellen auch der SQL-Query kürzer, handlicher und einfacher. - Im Grund gebe ich dir aber Recht, denn nach 3rd-NF sollte man die Daten in deren Einzelheit kleinstmöglich unterteilen und dann vom Typen her separat archivieren. - Ich versuche im SQL meine 3NF-Rgel nie zu brechen, aber in diesem Fall bot es sich einfach an.
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von Froschkoenig84 am .
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15.832

beantworten | zitieren | melden

Zitat von Froschkoenig84

Zweitens bin ich mir noch nicht sicher, ob ich gleich BSON (MongoDB) schreibe, aktuell habe ich aber noch keinen eigenen Server und werde vermutlich aus Kostengründen zunächst auf PostGreSQL zurückgreifen,
Sowas evaluiert man doch vorher..
Zitat von Froschkoenig84
Der Vorteil von PostGre ist, dass es sowohl JSON-Queries, als auch SQL-Queries unterstützt, auch wenn es vorwiegend relational aufgebaut ist.
Das kann stand heute fast jedes relationale Datenbanksystem - auch MSSQL.
Du missbrauchst das halt "etwas" - aus Faulheit? ;-)
Zitat von Froschkoenig84
Ich war früher nie ein Fan von NonSQL-DBs, aber ich nutze im Job inzwischen sehr gerne MongoDB und die Geschwindigkeit ist der Hammer
Kommt halt drauf an, was man macht.
Ich bin auch ein großer Fan von No-SQL Daten - aber oft passt halt auch NoSQL nicht.

Für ein Blog wie in diesem Fall aber sehr wohl.
So ein Mix hier empfinde ich aber als totalen Fehlritt.
private Nachricht | Beiträge des Benutzers
Regenwurm
myCSharp.de - Member



Dabei seit:
Beiträge: 295
Herkunft: Zentralschweiz

beantworten | zitieren | melden

Schon überprüft ob dein Problem nicht bereits vom verwendeten Datenbanksystem gelöst wird?
RavenDB 4 bietet zum Beispiel Document-Revisions an: https://ayende.com/blog/177665/ravendb-4-0-features-document-versioning
ServiceStack & Angular = =)
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1.977
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

PostgreSQL kannst du auch verwenden, spielt eigentlich kaum eine Rolle in diesem Szenario.
Da du einen einfachen Blog umsetzen willst, kannst du hier einfach mit einer History Tabelle zu deinen Beiträgen, die Daten wie bei Wikipedia zu versionieren.

Kannst du aber eigentlich auch mit einem MS SQL Server Express oder Standard machen.
Deinen Fall kannst du eigentlich mit einfachen Tabellen ohne JSON umsetzen.
Du musst dir dann nur einfach für deine Beiträge eindeutige ID und zu der ID dann jeweils die Versionen in einer History Tabelle ablegen.
Somit kannst du ohne JSON die Daten relational abspeichern.

T-Virus
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von T-Virus am .
Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
private Nachricht | Beiträge des Benutzers
Froschkoenig84
myCSharp.de - Member



Dabei seit:
Beiträge: 63
Herkunft: Scheibenwelt

Themenstarter:

beantworten | zitieren | melden

Jo, das ist der Plan.

Leider habe ich mich erst vor 3 Monaten zu eine RESTful-API (JSON) entschieden. Da ich vorher auch keine SPA geplant hatte.

Bisher existiert ja noch nicht viel von meinem Blog. Daher kann ich noch schieben und schummeln. Aber bis Ende des Jahres sollte das Ding zumindest laufen. Veröffentlichen würde ich ihn gerne im Februar 2019. - Viel Zeit, weiß ich. Aber es ist auch etwas größer als ein normaler Blog. :)

Vielen Dank für eure Hilfe. - Wenn ich live gehe, dürft ihr gerne mal ganz streng drüber gucken. :P
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15.832

beantworten | zitieren | melden

Dir ist schon klar, dass Suchmaschinen SPAs nicht wirklich (gut) indexieren können und es daher für einen Blog (noch) wenig Sinn macht?
Der Gedanke von API-First ist ja schon fast zu loben, aber für einen Blog....
Aber gut; Du wirst schon wissen, was Du da machst, mit der Bastelei :-)
private Nachricht | Beiträge des Benutzers
Froschkoenig84
myCSharp.de - Member



Dabei seit:
Beiträge: 63
Herkunft: Scheibenwelt

Themenstarter:

beantworten | zitieren | melden

@Abt:

Ist kein öffentlicher Blog :) Nur einzelne Subdomains werden öffentlich erreichbar sein. Suchmaschinen sind daher tatsächlich Nebensache. - Ich habe gezielt eine ganze bestimmte Nische im Auge. Es geht mir auch mehr um die Community hinter dem Blog. Wird auch mehr eine Pinnwand, als ein Forum/Blog, jedoch auch keine Kopie von Facebook. Wie gesagt, es geht um eine Nische. :)

Übrigens sind/waren die meisten Social-Communities für Suchmaschinen unerreichbar. Das gilt für Facebook, aber auch für Lokalisten, StudiVZ, MySpace, etc...

Ich habe natürlich auch vor ein paar einzelne Pages und Bereiche öffentlich zugänglich zu machen, damit wir nicht vollständig bei den Suchmaschinen rausfallen, aber der Großteil ist nur für Mitglieder einsehbar.

Ich verwende für die SPA natürlich die URL-Manipulation, um separate, valide URLs erzeugen zu können. Bspw.: sub.domain.tld/AREA/SUBAREA/PAGE/SUBPAGE/ auch wenn immer nur die eine physische Datei aufgerufen wird, werde ich via JavaScript history.pushState() (etwas vergleichbares unterstützen seit 3-4 Jahren eigentlich alle bekannten Browser) den URL so manipulieren, dass ich quasi immer neue URLs erhalte und via JS und RESTful-API im Hintergrund eben nur noch der Content ausgetauscht, bzw. regeneriert wird.

* https://developer.mozilla.org/de/docs/Web/Guide/DOM/Manipulating_the_browser_history
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Froschkoenig84 am .
private Nachricht | Beiträge des Benutzers