TINYINT(1) – Integer oder Boolean?

Ich hätte nicht gedacht, das ich mir diese Frage bei einem Datentyp in MariaDB mal stellen würde, aber gestern stellte ich fest, dass ein TINYINT nicht unbedingt als Integer behandelt wird – je nach Backend.

In einem meiner Discord-Bots die ich entwickle, speichere ich Daten in einer MariaDB. Und eines der Spalten ist für einen Statuswert gedacht, der in Zahlen ausgedrückt wird und dann entsprechend von meinem Bot interpretiert wird, also sowas wie:

0 = Open
1 = Closed
2 = Expired
3 = Rejected

Naheliegend ist die Spalte in der Datenbank dann eine kleinstmögliche Integer-Spalte, also ein TINYINT. Man gibt zusätzlich noch einen Zahlenwert mit an, die die Spaltenbreite für diverse Datenbank-Clients enthält – also Beispielsweise TINYINT(1) für eine Spaltenbreite von 1. Da das für mich völlig ausreicht um meine vier Statuswerte zu speichern, habe ich meine MariaDB-Spalte exakt so konfiguriert.

In meinem Discord-Bot nutze ich MySqlConnector für die Datenbankverbindung. Für die Statuswerte habe ich ein kleines Enum geschrieben, dass die Zahlenwerte so wie die Beschreibung definiert:

public enum RequestState  
{
      Open = 0,
      Closed = 1,
      Expired = 2,
      Rejected =3  
}

Und für die Zuweisung das übliche Vorgehen:
while (await reader.ReadAsync())
{
    //  ...
    var requestState = (RequestState)reader.GetInt16(7); // Is completed
    // ...
}

Und hier wurde es kurios. Der eingelesene Integer war immer 0 oder 1, niemals eine andere Zahl, unabhängig davon, was in der Datenbank stand. Ich hab’s nicht begriffen und fing an zu googlen und merkte, das ich nicht der einzige bin, der auf genau dieses Problem stieß. Die Antworten waren teilweise sehr mehrdeutig und auch auf verschiedene Applikationen, Frameworks und Libraries bezogen. Im Allgemeinen hieß es immer TINYINT(1) gibt nur ein Boolean (0 oder 1) zurück. Der Standard in MySQL wäre ein Byte-Datentyp. Aber das half mir alles nicht weiter. Und dann fand ich einen Beitrag, der erklärte das TINYINT(1) häufig in Backendsystemen als Boolean genutzt und damit auch erzwungen wird und sobald ich die MariaDB-Spalte auf TINYINT(2) ändere, wäre das Problem damit gelöst.

Was? Die vordefinierte Spaltenbreite erhöhen soll die Interpretation von TINYINT ändern? Konnte ich mir nicht vorstellen, aber doch, genau so war es. Ich änderte meine Datenbankspalte entsprechend ab und lies mein Bot erneut seine Aktion durchführen und voila: Ich hatte plötzlich auch 2er und 3er in den Ergebnissen!

Also TLDR: TINYINT(1) = Es gibt nur 0 und 1 in MySqlConnector. Alles über 1 wird einfach als eine 1 interpretiert. Willst du tatsächlich Integer-Werte haben, ändere die Spalte auf TINYINT(2).

Man lernt einfach nie aus und selbst nach vielen Jahren als Entwickler, entdeckt man immer wieder was neues, das für andere vermutlich selbstverständlich ist.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert