Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #27. COLLATE bei mariaDB #498

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Conversation

lenilsas
Copy link

Beim anlegen der DB bei Mariadb und Charset utf8mb4 kam es zu Fehlern. Mit ROW_FORMAT=DYNAMIC funktioniert es wieder.

Resolve #27

@dippeal
Copy link
Member

dippeal commented Nov 27, 2024

Laut Dokumentation von https://dev.mysql.com/doc/refman/8.4/en/innodb-row-format.html und https://mariadb.com/kb/en/innodb-row-formats-overview/ soll bei den Servern die default row format bereits DYNAMIC sein.
Den default Wert noch mal zu setzen wird sicherlich nicht problematisch sein, wundert mich aber etwas.

@dippeal dippeal added the fix This will fix a bug label Nov 27, 2024
@lenilsas lenilsas changed the title Fix #27. ROW FORMAT bei mariaDB Fix #27. COLLATE bei mariaDB Nov 27, 2024
@lenilsas
Copy link
Author

Mit geänderter Codierung (Collate) funktioniert es jetzt.
Ich nutze diese Codierung (latin1) schon immer ohne Schwierigkeiten.

@@ -1026,7 +1026,7 @@ private void update0028(Connection conn) throws ApplicationException
sb.append(" rechnungfuerbarzahlung CHAR(5),");
sb.append(" UNIQUE (id),");
sb.append(" PRIMARY KEY (id)");
sb.append(" ) ENGINE=InnoDB;\n");
sb.append(" ) ENGINE=InnoDB COLLATE='latin1_swedish_ci';\n");
Copy link
Member

@tolot27 tolot27 Dec 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Das würde ich auf keinen Fall setzen, da es Unicode nicht richtig bzw. gar nicht unterstützt. Es ist auch endlich als default entfernt worden (siehe MDEV-19123).

Da wir nicht MariaDB v11 voraussetzen, sondern auch niedrigere Versionen unterstützen, sollten wir wenigsten utf8mb4_unicode_520_ci verwenden. Das wird auch von MySQL ab 5.6 unterstützt.

Noch besser wäre utf8mb4_0900_ai_ci, da es immerhin schon Unicode 9 unterstützt (released 20216) und seit MySQL 8.0.1 verfügbar ist, leider jedoch nicht in MariaDB. MariaDB unterstützt wiederum uca1400_ai_ci, welche nicht von MySQL unterstützt wird. Uns bleibt also momentan nur utf8mb4_unicode_520_ci als Maximalversion (siehe auch https://www.coderedcorp.com/blog/guide-to-mysql-charsets-collations/#toc_7).

Oder haben wir Code, der zwischen MySQL und MariaDB unterscheidet? WIe es mit H2 aussieht, weiß ich momentan noch nicht.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ich verwende 10.11.8-MariaDB-0ubuntu0.24.04.1
Das Problem ist, dass bei MSQL/MariaDB eine maximale Zeilengröße besteht, bei innoDB beträgt die 8126 Bytes beträgt. Beim nachträglichen einfügen von Spalten wird dieses Limit aber nicht kontrolliert. Die utf8 Codierungen verwenden 4Bytes pro Zeichen (bzw es werden 4 reserviert) und dadurch wird bei den Einstellungen die Grenze überschritten. Die andere Codierung wird ja nur für die Eintellungen Tabelle verwendet, da kommt man in den allermeisten fällen auch mit latin1 klar da JVerein ja auch nur für den deutschsprachigen Raum entwickelt wird, da sollten man meistens auch ohne chinesische Zeichen o.ä. auskommen.
Aber natürlich ist das eher ein Workaround. Eine andere Möglichkeit den Fehler zu beheben wäre die Struktur der Einstellungentabelle zu verändern, z.B. mit nur den Spalten key und value und für jede Einstellung eine Zeile. Das würde auch das nachträgliche hinzufügen von Einstellungen erleichtern, da nicht immer die Tabelle verändert werden muss sondern nur eine Zeile hinzugefügt wird.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

COLLATE hat jedoch überhaupt keinen Einfluss auf die Zeilengröße, sondern nur, wie textbasierte Zellen/Werte verglichen werden. Insofern halte ich die Verwendung einer anderen COLLATION nicht für die Lösung des Problems.

Copy link
Member

@tolot27 tolot27 Dec 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eine andere Möglichkeit den Fehler zu beheben wäre die Struktur der Einstellungentabelle zu verändern, z.B. mit nur den Spalten key und value und für jede Einstellung eine Zeile. Das würde auch das nachträgliche hinzufügen von Einstellungen erleichtern, da nicht immer die Tabelle verändert werden muss sondern nur eine Zeile hinzugefügt wird.

Das klingt doch gut. So macht es glaub ich auch Hibiscus bei einigen Tabellen. Hat auch was hinsichtlich Normalisierung. 😏

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

COLLATE hat jedoch überhaupt keinen Einfluss auf die Zeilengröße, sondern nur, wie textbasierte Zellen/Werte verglichen werden. Insofern halte ich die Verwendung einer anderen COLLATION nicht für die Lösung des Problems.

Soweit ich verstanden habe wird durch die andere COLLATION auch eine andere Codierung verwendet. Auf jeden Fall hat die Änderung bei mir funktioniert.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

COLLATE hat jedoch überhaupt keinen Einfluss auf die Zeilengröße, sondern nur, wie textbasierte Zellen/Werte verglichen werden. Insofern halte ich die Verwendung einer anderen COLLATION nicht für die Lösung des Problems.

Soweit ich verstanden habe wird durch die andere COLLATION auch eine andere Codierung verwendet. Auf jeden Fall hat die Änderung bei mir funktioniert.

Ne, dass kann nicht sein. Dafür ist CHARSET da. COLLATE ist ausschließlich für Vergleiche da. Das es ggf. funktioniert, hat andere Ursachen. Wenn ich es nachstellen könnte, kann ich es korrekt implementieren.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Laut https://mariadb.com/kb/en/setting-character-sets-and-collations/ wird die Charset automatisch gesetzt wenn die Collation gesetzt wird:

It is also possible to specify only the collation, and, since each collation only applies to one character set, the associated character set will automatically be specified.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, danke für die Info. Das wusste ich noch nicht. Ich mag solche impliziten Dinge nicht, da es schwierig nachzuvollziehen ist. Es macht es in meinen Augen auch noch problematischer. Wir verwenden bereits im connection string UTF8 und dann wird es in der DB nur noch als latin1 mit einem Byte gespeichert. Da gehen Informationen verloren.

Die andere Codierung wird ja nur für die Eintellungen Tabelle verwendet, da kommt man in den allermeisten fällen auch mit latin1 klar da JVerein ja auch nur für den deutschsprachigen Raum entwickelt wird, da sollten man meistens auch ohne chinesische Zeichen o.ä. auskommen.

Ich glaub so wenige Fälle sind das gar nicht. Wir haben in unserer E-Mail-Signatur Personennamen drin, die Zeichen enthalten, die nicht latin1 sind. Durch diesen PR würden sie umcodiert werden.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eine temporäre Lösung könnte sein, ENGINE=InnoDB CHARACTER SET latin1 COLLATE latin1_german1_ci ROW_FORMAT=DYNAMIC zu verwenden und bei Feldern, in denen unicode Zeichen potentiell eingefügt werden könnten (name, mailsignatur und optional auch strasse und smtp_from_anzeigename), explizit mit CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci anzulegen. Das sollte die Größe der Tabelle etwas kleiner halten. Wobei natürlich mailsignatur trotzdem mit 4 kB zu Buche schlägt. So könnte man das row limit jedoch erstmal einhalten.

Alternativ kann man die innodb page size auf 32 kB anheben und erhält so fast 16 kB row size. Das halte ich jedoch nicht für zielführend, da dadurch der SQL Server umkonfiguriert werden muss.

Die Tabelle zu normalisieren, ist definitiv mittelfristig der richtig Weg.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ich habe deinen Vorschlag jetzt umgesetzt.

Bei größeren Varchar oder Text Feldern werden immer nur die ersten 256 Bytes in der Tabelle direkt gespeichert, die restlichen in overflow pages daher ist die Länge unwesentlich.

Copy link
Member

@tolot27 tolot27 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sollten wir die bereits existierende Einstellungstabelle (vorhandene Installation) nicht auch aktualisieren? So bekommen wir einen definierten Zustand der existierenden und neu installierten DBs. Sonst schlägt vielleicht das nächste Feldhinzufügen fehl.

src/de/jost_net/JVerein/server/JVereinUpdateProvider.java Outdated Show resolved Hide resolved
@lenilsas
Copy link
Author

Sollten wir die bereits existierende Einstellungstabelle (vorhandene Installation) nicht auch aktualisieren? So bekommen wir einen definierten Zustand der existierenden und neu installierten DBs. Sonst schlägt vielleicht das nächste Feldhinzufügen fehl.

Das ist das was ich nicht verstehe. Beim erstellen der Tabelle in einem rutsch mit allen Befehlen hintereinander schlägt es fehl. Wenn man jedoch später eine Spalte hinzufügt kommt kein Fehler.
Ich denke wir werden bald die Einstellungentabelle ändern und dann haben wir es einheitlich, das hier ist dann nur ein schnelle Behebung für die Zwischenzeit, von dem her würde ich es so lassen. Bisher sind ja auch gar keine Charsets definiert und es wird immer die default Charset des Systems verwendet.

tolot27
tolot27 previously approved these changes Dec 20, 2024
@lenilsas lenilsas requested a review from dippeal December 26, 2024 15:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fix This will fix a bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unknown column 'sterbedatum' at setup with MySQL
3 participants