• Für viele Anwendungen benötigt man eine Nutzerdatenbank. Hier zeige ich kurz wie man diese anlegt.
  • Hier werden Trigger eingesetzt:
    • Um das Logging der Änderungen zu übernehmen.
    • Und um zu garantieren, dass Passwörter immer gesalzen und gehasht sind.
  • Das heißt, dass die Anwendung, welche mit der Datenbank verbunden wird:
    • Benutzername und Passwortabfragen selbst mit der Datenbank vergleicht (wie sonst auch).
    • Passwörter von der Anwendung im Klartext an die Datenbank übergeben werden (statt das Salz und gehashtes Passwort der Datenbank übergeben werden).
  • Fehler? Ergänzungen? Fragen? Schreib mir.

tl;dr

  • Nur die Vorbereitunsgschritte ausführen.
  • Ein SQL-Skript aller Schritte ist am Ende dieses Beitrages.

Vorbereitung: System Setup

Beispielsetup unter Arch Linux.

  • sudo pacman -S mariadb
  • sudo mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
  • sudo systemctl start mysqld
  • sudo mysql_secure_installation
    • Hier werden nun einige Fragen gestellt.
    • Ich habe nach der Root-Passworteingabe alles mit Ja beantwortet, da ich die Datenbank nur lokal zu Test-Zwecken einsetze.
  • sudo mysql_upgrade -u root -p
    • Nur nach einem Upgrade der MariaDB Version (Major und Minor).

Vorbereitung: Nutzer anlegen

  • mysql -u root -p
    • Als Root-Benutzer einloggen.
  • MariaDB> CREATE USER 'frank'@'localhost' IDENTIFIED BY 'some_password';
  • MariaDB> GRANT ALL PRIVILEGES ON frank.* TO 'frank'@'localhost';
    • Der Name der Datenbank muss nicht mit dem Nutzernamen übereinstimmen.
    • Für jeder weitere Datenbank muss dieser Vorgang wiederholt werden.
    • Der * ist ein Platzhalter, sodass die PRIVILEGES für alle Tabellen erteilt werden.
  • MariaDB> FLUSH PRIVILEGES;
  • MariaDB> quit

Vorbereitung: Trigger

  • Trigger stehen normaler Weise im Konflikt mit Replication.
  • Diese kann man dennoch mit und ohne Replication verwenden.

Mit Replication

  • mysql -u root -p
  • MariaDB> SET GLOBAL log_bin_trust_function_creators = 1;
  • MariaDB> quit
  • sudo nano /etc/mysql/my.cnf
    • Mit dem Editor der Wahl die Config-Datei öffnen.
    • Und wie folgt ändern:
# Replication Master Server (default)
# binary logging is required for replication
log-bin=mysql-bin

# binary logging format - mixed recommended
binlog_format=mixed

expire_logs_days = 10
max_binlog_size = 100M

Das Anfügen des Ablaufdatums und der Log-Größe beschränkt das binlog, sodass die Platte nicht voll laufen kann.

  • sudo systemctl restart mysqld
    • MariaDB neu starten.

Ohne Replication

  • sudo nano /etc/mysql/my.cnf
    • Das binlog wie in den folgenden Zeilen auskommentieren:
# Replication Master Server (default)
# binary logging is required for replication
# log-bin=mysql-bin

# binary logging format - mixed recommended
# binlog_format=mixed
  • sudo systemctl restart mysqld
    • MariaDB neu starten.

Datenbank anlegen

  • mysql -u frank -p
  • Hier sind zwei Beispiele um die Tabellen sauber wieder anzulegen.
  • Wenn die Datenbank leer ist kann man sie löschen und wieder anlegen.
  • Sollten andere Tabellen bereits in der Datenbank sein, sollte man nur die betreffenden Tabellen löschen.
  • Hier benötigt man SET FOREIGN_KEY_CHECKS = 0; eigentlich nicht, da hier keine Fremdschlüssel verwendet werden.
  • Ich habe dies dennoch drin gelassen, damit der geneigte nutzer diesen Workaround an anderer Stelle verwenden kann.
PROMPT MariaDB [\u@\h (\d)]> 

-- Drop database with included tables.
DROP DATABASE IF EXISTS frank;
-- Recreate database.
CREATE DATABASE frank;
-- Use new database.
USE frank

-- Suppress error message on foreign keys.
SET FOREIGN_KEY_CHECKS = 0;
-- Drop tables with included tables.
DROP Table IF EXISTS dbuser;
DROP Table IF EXISTS dblog;
-- Reset foreign key check.
SET FOREIGN_KEY_CHECKS = 1;

Tabellen anlegen

  • Die Einträge in der Nutzerdatenbank dbuser enthalten
    • ID,
    • Nutzernamen,
    • Passwort,
    • Salz zum Passwort
    • Und ein Infofeld.
  • Die ID ist der Primärschlüssel und der Nutzername muss eindeutig sein.
  • Passwörter und Salz kann man statt mittels VARBINARY(64) platzsparender als VARCHAR(64) abspeichern.
    • Zu beachten wäre, dass alle Werte in diesem Fall UNHEX(SHA2(...)) benötigen.
  • Das Logbuch enthält
    • Den Zeitstempel des Ereignisses,
    • Den Namen des Datenbank-Nutzers, welcher die Änderung durchführt,
    • Welche Art (INSERT, UPDATE, DELETE, WARNING) die Änderung ist und
    • Was geändert wurde.
CREATE TABLE dbuser (
    db_userid INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    db_username VARCHAR(45) NOT NULL,
    db_userpassword VARCHAR(64) NOT NULL,
    -- db_userpassword VARBINARY(64) NOT NULL,
    -- And use `UNHEX(SHA2(...))` instead of `SHA2(...)`.
    -- I like to read the hash values, so I do not use bin values.
    db_usersalt VARCHAR(16) NOT NULL,
    db_userinfo VARCHAR(192),
    
    PRIMARY KEY(db_userid),
    UNIQUE (db_username)
) ENGINE = InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE dblog (
    db_logtime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    db_logusername VARCHAR(45) NOT NULL,
    db_logaction VARCHAR(20) NOT NULL,
    db_loginfo VARCHAR(512) NOT NULL
) ENGINE = InnoDB DEFAULT CHARSET=utf8;

Trigger: Neuer Nutzer

  • Der neue Nutzername wird in Kleinbuchstaben abgespeichert.
  • MariaDB erzeugt das Salz durch Multiplikation einer Zufallszahl mit der aktuellen Zeit und bildet darüber einen SHA256-Hash.
    • Man kann sich streiten, ob man das Datum mit hinein multipliziert.
  • An das Passwort wird mit das Salz angefügt und SHA256-gehasht.
DELIMITER //
CREATE TRIGGER bi_dbuser BEFORE INSERT ON dbuser FOR EACH ROW 
BEGIN
    -- Insert new username and password.
    SET NEW.db_username = LOWER(NEW.db_username);
    SET NEW.db_usersalt = SUBSTRING(SHA2(CURRENT_TIMESTAMP * RAND(), 256), -16);
    SET NEW.db_userpassword = SHA2(CONCAT(NEW.db_userpassword, NEW.db_usersalt), 256);
    -- Log.
    INSERT INTO dblog (db_logusername, db_logaction, db_loginfo)
    VALUES (CURRENT_USER, 'INSERT', CONCAT('New user: `', New.db_username,'`.'));
END //
DELIMITER ;

Trigger: Nutzerdaten aktualisieren

  • Wenn ein Nutzername oder Passwort geändert wird.
  • Würde man auf eine Protokollierung verzichten, würde man einfach nur den Teil unter Without logging. verwenden.
  • Zu beachten ist, dass NEW.db_userpassword = OLD.db_userpassword nur dann Wahr ist, wenn über das SQL-Statement kein db_userpassword angegeben wurde. Auch wenn hier das gleiche Passwort wie hinter dem gesalzene Hash eingegeben wird, ist diese Aussage nicht wahr.
  • Username.
    • Wird der gleiche db_username eingegeben wird hier nichts gemacht.
    • Sonst wird der Nutzername geändert.
    • Wird dazu kein db_userpassword übergeben wird hier der Log-Eintrag geschrieben.
  • Password.
    • Wird nur ausgeführt, wenn ein db_userpassword mit dem Statement übergeben wird.
    • Ist der gesalzene Hash vom übergebenen db_userpassword verschieden vom dem in der Datenbank:
      • Wird ein neues Salz erzeugt und mit dem übergeben Passwort verbunden und gehasht.
      • Der dazugehörige Log-Eintrag ist davon abhängig, ob auch der Nutzername geändert wurde.
    • Wenn der gesalzene Hash vom übergebenen db_userpassword gleich vom dem in der Datenbank ist:
      • Werden die bisherigen Werte wieder in die Datenbank geschrieben.
      • Sollte man dies explizit nicht machen, wird das Passwort im wie übergeben (im Klartext) abgespeichert.
      • Ein Log-Eintrag wird dennoch geschrieben. So wird klar, dass versucht wurde das Passwort zu ändern.
        • Dieses Logging kann man auch weg lassen.
DELIMITER //
CREATE TRIGGER bu_dbuser BEFORE UPDATE ON dbuser FOR EACH ROW 
BEGIN

    -- Without logging.
--	SET NEW.db_username = lower(NEW.db_username);
--	IF (NEW.db_userpassword <> OLD.db_userpassword) THEN
--	    SET NEW.db_usersalt = SUBSTRING(SHA2(CURRENT_TIMESTAMP * RAND(), 256), -16);
--        SET NEW.db_userpassword = SHA2(CONCAT(NEW.db_userpassword, NEW.db_usersalt), 256);
--	END IF;

    -- Username.
    IF (OLD.db_username <> LOWER(NEW.db_username)) THEN
        -- Change username.
        SET NEW.db_username = LOWER(NEW.db_username);
        -- Log.
        -- When no password is given to compare.
        IF (NEW.db_userpassword = OLD.db_userpassword) THEN
            INSERT INTO dblog (db_logusername, db_logaction, db_loginfo)
            VALUES (CURRENT_USER, 'UPDATE', CONCAT('Change username `', OLD.db_username, '` in `', NEW.db_username,'`.'));
        END IF;
    END IF;
    
    -- Password.
    -- When a password is given in sql statement. If it is the same or not is unknown now.
    IF (NEW.db_userpassword <> OLD.db_userpassword) THEN
        -- If the given password is not the same as the existing password.
        IF (SHA2(CONCAT(NEW.db_userpassword, OLD.db_usersalt), 256) <> OLD.db_userpassword) THEN
            -- Change password with new salt.
            SET NEW.db_usersalt = SUBSTRING(SHA2(RAND(),256), -16);
            SET NEW.db_userpassword = SHA2(CONCAT(NEW.db_userpassword, NEW.db_usersalt), 256);
            -- Log.
            IF (OLD.db_username <> LOWER(NEW.db_username)) THEN
                INSERT INTO dblog (db_logusername, db_logaction, db_loginfo) 
                VALUES (CURRENT_USER, 'UPDATE', CONCAT('Change username `', OLD.db_username, '` in `', NEW.db_username,'` and change password of this user.'));
            ELSE
                INSERT INTO dblog (db_logusername, db_logaction, db_loginfo) 
                VALUES (CURRENT_USER, 'UPDATE', CONCAT('Change password of user `', NEW.db_username,'`.'));
            END IF;
        -- If the given password is the same as the existing password.
        ELSE
            -- We use the old entries. If not, the password will be written as plain text.
            SET NEW.db_usersalt = OLD.db_usersalt;
            SET NEW.db_userpassword = OLD.db_userpassword;
            -- Log.
            IF (OLD.db_username <> LOWER(NEW.db_username)) THEN
                INSERT INTO dblog (db_logusername, db_logaction, db_loginfo) 
                VALUES (CURRENT_USER, 'UPDATE', CONCAT('Change username `', OLD.db_username, '` in `', NEW.db_username,'` and no password change.'));
            ELSE
                INSERT INTO dblog (db_logusername, db_logaction, db_loginfo) 
                VALUES (CURRENT_USER, 'UPDATE', CONCAT('No password change on user `', OLD.db_username,'`.'));
            END IF;
        END IF;
    END IF;

END //
DELIMITER ;

Trigger: Nutzer löschen

  • Dies ist der einfachste Trigger.
  • Wenn ein Nutzer gelöscht wurde, wird im Logbuch hinterlegt, wer wann wen gelöscht hat.
CREATE TRIGGER ad_dbuser AFTER DELETE ON dbuser FOR EACH ROW 
INSERT INTO dblog (db_logusername, db_logaction, db_loginfo)
VALUES (CURRENT_USER, 'DELETE', CONCAT('Delete user `', OLD.db_username,'`.'));

Benutzer hinzufügen

INSERT INTO dbuser
    (db_username, db_userpassword) 
VALUES
    ('eins', '111'),
    ('zwei', '222'),
    ('drei', '333'),
    ('vier', '444'),
    ('geheim', 'geheim'),
    ('Batman', 'Robin'),
    ('fünf', '555'),
    ('sechs', '666'),
    ('sieben', '777'),
    ('acht', '898'),
    ('foobar', 'geheim')
;

SELECT * FROM dbuser;

Nutzerdaten ändern (1/2)##

  • Hier werden die Nutzerdaten geändert.
  • Dabei werden nur die Daten in das Statement geschrieben, die auch geändert werden sollen.
  • Es gibt neue Daten, die den alten Daten entsprechen.
    • Dies sollte nichts am Inhalt der Tabelle ändern.
-- Change no username only.
UPDATE dbuser
SET db_username='eins'
    , db_userinfo='Change no username only.'
WHERE db_username='eins';

-- Change username only.
UPDATE dbuser
SET db_username='zwo'
    , db_userinfo='Change username only.'
WHERE db_username='zwei';

-- Change no password only.
UPDATE dbuser
SET db_userpassword='333'
    , db_userinfo='Change no password only.'
WHERE db_username='drei';

-- Change password only.
UPDATE dbuser
SET db_userpassword='four'
    , db_userinfo='Change password only.'
WHERE db_username='vier';

-- Check for delete log.
DELETE FROM dbuser
WHERE db_username='batman';

-- See results.
SELECT * FROM dbuser;

Nutzerdaten ändern (2/2)

  • Hier werden Nutzerdaten geändert.
  • Dabei werden auch die Daten in das Statement geschrieben, die nicht geändert werden sollen.
-- Change no username but password.
UPDATE dbuser
SET 
    db_username='fünf',
    db_userpassword='five'
    , db_userinfo='Change no username but password.'
WHERE db_username='fünf';

-- Change no username but no password.
UPDATE dbuser
SET 
    db_username='sechs',
    db_userpassword='666'
    , db_userinfo='Change no username and no password.'
WHERE db_username='sechs';

-- Change username and no password.
UPDATE dbuser
SET 
    db_username='seven',
    db_userpassword='777'
    , db_userinfo='Change username and no password.'
WHERE db_username='sieben';

-- Chance username and password.
UPDATE dbuser
SET 
    db_username='eight',
    db_userpassword='eight'
    , db_userinfo='Change username and password.'
WHERE db_username='acht';

SELECT * FROM dbuser;

Datenbankinformationen ausgeben

SHOW DATABASES;
SHOW TABLES;

DESCRIBE dbuser;
DESCRIBE dblog;

SELECT * FROM dbuser;
SELECT * FROM dblog;

SQL-Skript

  • Alle obigen Schritte in einem Skript.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
/* ** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */

/* If a super privileges error occurs: Do 1) or 2). */

-- 1)
/* *** *** *** *** *** 
mysql> SET GLOBAL log_bin_trust_function_creators = 1;

And change config file: /etc/mysql/my.cnf
# Replication Master Server (default)
# binary logging is required for replication
log-bin=mysql-bin

# binary logging format - mixed recommended
binlog_format=mixed
expire_logs_days = 10
max_binlog_size = 100M
*/

-- 2)
/* *** *** *** *** *** 
Change config file: /etc/mysql/my.cnf 
# Replication Master Server (default)
# binary logging is required for replication
#log-bin=mysql-bin

# binary logging format - mixed recommended
#binlog_format=mixed
#expire_logs_days = 10
#max_binlog_size = 100M
*/

/* ** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */


PROMPT MariaDB [\u@\h (\d)]> 

-- Drop database with included tables.
DROP DATABASE IF EXISTS frank;
-- Recreate database.
CREATE DATABASE frank;
-- Use new database.
USE frank

-- Suppress error message on foreign keys.
SET FOREIGN_KEY_CHECKS = 0;
-- Drop tables with included tables.
DROP Table IF EXISTS dbuser;
DROP Table IF EXISTS dblog;
-- Reset foreign key check.
SET FOREIGN_KEY_CHECKS = 1;


/* *****************************************************************************
*   User tables.
***************************************************************************** */

CREATE TABLE dbuser (
    db_userid INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    db_username VARCHAR(45) NOT NULL,
    db_userpassword VARCHAR(64) NOT NULL,
    -- db_userpassword VARBINARY(64) NOT NULL,
    -- And use `UNHEX(SHA2(...))` instead of `SHA2(...)`.
    -- I like to read the hash values, so I do not use bin values.
    db_usersalt VARCHAR(16) NOT NULL,
    db_userinfo VARCHAR(192),
    
    PRIMARY KEY(db_userid),
    UNIQUE (db_username)
) ENGINE = InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE dblog (
    db_logtime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    db_logusername VARCHAR(45) NOT NULL,
    db_logaction VARCHAR(20) NOT NULL,
    db_loginfo VARCHAR(512) NOT NULL
) ENGINE = InnoDB DEFAULT CHARSET=utf8;


/* *****************************************************************************
*   User table trigger.
***************************************************************************** */

DELIMITER //
CREATE TRIGGER bi_dbuser BEFORE INSERT ON dbuser FOR EACH ROW 
BEGIN
    -- Insert new username and password.
    SET NEW.db_username = LOWER(NEW.db_username);
    SET NEW.db_usersalt = SUBSTRING(SHA2(CURRENT_TIMESTAMP * RAND(), 256), -16);
    SET NEW.db_userpassword = SHA2(CONCAT(NEW.db_userpassword, NEW.db_usersalt), 256);
    -- Log.
    INSERT INTO dblog (db_logusername, db_logaction, db_loginfo)
    VALUES (CURRENT_USER, 'INSERT', CONCAT('New user: `', New.db_username,'`.'));
END //
DELIMITER ;

DELIMITER //
CREATE TRIGGER bu_dbuser BEFORE UPDATE ON dbuser FOR EACH ROW 
BEGIN

    -- Without logging.
--	SET NEW.db_username = lower(NEW.db_username);
--	IF (NEW.db_userpassword <> OLD.db_userpassword) THEN
--	    SET NEW.db_usersalt = SUBSTRING(SHA2(CURRENT_TIMESTAMP * RAND(), 256), -16);
--        SET NEW.db_userpassword = SHA2(CONCAT(NEW.db_userpassword, NEW.db_usersalt), 256);
--	END IF;

    -- Username.
    IF (OLD.db_username <> LOWER(NEW.db_username)) THEN
        -- Change username.
        SET NEW.db_username = LOWER(NEW.db_username);
        -- Log.
        -- When no password is given to compare.
        IF (NEW.db_userpassword = OLD.db_userpassword) THEN
            INSERT INTO dblog (db_logusername, db_logaction, db_loginfo)
            VALUES (CURRENT_USER, 'UPDATE', CONCAT('Change username `', OLD.db_username, '` in `', NEW.db_username,'`.'));
        END IF;
    END IF;
    
    -- Password.
    -- When a password is given in sql statement. If it is the same or not is unknown now.
    IF (NEW.db_userpassword <> OLD.db_userpassword) THEN
        -- If the given password is not the same as the existing password.
        IF (SHA2(CONCAT(NEW.db_userpassword, OLD.db_usersalt), 256) <> OLD.db_userpassword) THEN
            -- Change password with new salt.
            SET NEW.db_usersalt = SUBSTRING(SHA2(RAND(),256), -16);
            SET NEW.db_userpassword = SHA2(CONCAT(NEW.db_userpassword, NEW.db_usersalt), 256);
            -- Log.
            IF (OLD.db_username <> LOWER(NEW.db_username)) THEN
                INSERT INTO dblog (db_logusername, db_logaction, db_loginfo) 
                VALUES (CURRENT_USER, 'UPDATE', CONCAT('Change username `', OLD.db_username, '` in `', NEW.db_username,'` and change password of this user.'));
            ELSE
                INSERT INTO dblog (db_logusername, db_logaction, db_loginfo) 
                VALUES (CURRENT_USER, 'UPDATE', CONCAT('Change password of user `', NEW.db_username,'`.'));
            END IF;
        -- If the given password is the same as the existing password.
        ELSE
            -- We use the old entries. If not, the password will be written as plain text.
            SET NEW.db_usersalt = OLD.db_usersalt;
            SET NEW.db_userpassword = OLD.db_userpassword;
            -- Log. 
            -- If in doubt leave it out.
            IF (OLD.db_username <> LOWER(NEW.db_username)) THEN
                INSERT INTO dblog (db_logusername, db_logaction, db_loginfo) 
                VALUES (CURRENT_USER, 'UPDATE', CONCAT('Change username `', OLD.db_username, '` in `', NEW.db_username,'` and no password change.'));
            ELSE
                INSERT INTO dblog (db_logusername, db_logaction, db_loginfo) 
                VALUES (CURRENT_USER, 'UPDATE', CONCAT('No password change on user `', OLD.db_username,'`.'));
            END IF;
        END IF;
    END IF;

END //
DELIMITER ;

CREATE TRIGGER ad_dbuser AFTER DELETE ON dbuser FOR EACH ROW 
INSERT INTO dblog (db_logusername, db_logaction, db_loginfo)
VALUES (CURRENT_USER, 'DELETE', CONCAT('Delete user `', OLD.db_username,'`.'));


/* *****************************************************************************
*   Content.
***************************************************************************** */

INSERT INTO dbuser
    (db_username, db_userpassword) 
VALUES
    ('eins', '111'),
    ('zwei', '222'),
    ('drei', '333'),
    ('vier', '444'),
    ('geheim', 'geheim'),
    ('Batman', 'Robin'),
    ('fünf', '555'),
    ('sechs', '666'),
    ('sieben', '777'),
    ('acht', '898'),
    ('foobar', 'geheim')
;

SELECT * FROM dbuser;

-- Change no username only.
UPDATE dbuser
SET db_username='eins'
    , db_userinfo='Change no username only.'
WHERE db_username='eins';

-- Change username only.
UPDATE dbuser
SET db_username='zwo'
    , db_userinfo='Change username only.'
WHERE db_username='zwei';

-- Change no password only.
UPDATE dbuser
SET db_userpassword='333'
    , db_userinfo='Change no password only.'
WHERE db_username='drei';

-- Change password only.
UPDATE dbuser
SET db_userpassword='four'
    , db_userinfo='Change password only.'
WHERE db_username='vier';

-- Check for delete log.
DELETE FROM dbuser
WHERE db_username='batman';

-- See results.
SELECT * FROM dbuser;


-- Change no username but password.
UPDATE dbuser
SET 
    db_username='fünf',
    db_userpassword='five'
    , db_userinfo='Change no username but password.'
WHERE db_username='fünf';

-- Change no username but no password.
UPDATE dbuser
SET 
    db_username='sechs',
    db_userpassword='666'
    , db_userinfo='Change no username and no password.'
WHERE db_username='sechs';

-- Change username and no password.
UPDATE dbuser
SET 
    db_username='seven',
    db_userpassword='777'
    , db_userinfo='Change username and no password.'
WHERE db_username='sieben';

-- Chance username and password.
UPDATE dbuser
SET 
    db_username='eight',
    db_userpassword='eight'
    , db_userinfo='Change username and password.'
WHERE db_username='acht';

SELECT * FROM dbuser;


/* *******************************************************************
* Show something: Over the rainbow. ;-)
******************************************************************* */

SHOW DATABASES;
SHOW TABLES;

DESCRIBE dbuser;
DESCRIBE dblog;

SELECT * FROM dbuser;
SELECT * FROM dblog;