a Monster in SQL

Eine Schande Namens Datenbank Design

Ursprünglich wollt ich nur was zu MSSQL sagen aber das währe zu kurz gegriffen, denn auch MSSQL bietet irgendwo seine Vorteile und hat wahrscheinlich in den Augen seiner Schöpfer seine Daseinsberechtigung. Es ist eher der Designer also das Management Studio was mich anwürgt.

Wer schon einmal versucht hat aus diesem Studio heraus ein DB Dump zu machen um eventuell die gesamte Datenbank in ein anderes Format zu schaufeln der weiß wie leidensfähig man sein muss wenn es um MSSQL geht.

Ich hab irgendwann aufgegeben nenn Converter zu suchen und hab mir die Skripte alle selbst geschrieben samt DB Connector. Was mich im Endeffekt nur Minuten gekostet hat.

Will man hingegen nurn Backup machen, läuft die ganze Sache Rechtsklick Sichern … fertig, wieder in MSSQL einspielen sollte da weniger das Problem sein. Wenn der Designer nicht für Masochisten währe ja.

Ein Beispiel gefällig?

mysqldump -u **** -p --no-create-info {databasename} > {path}/{filename}.sql

Man gibt noch eventuell einen Pfad an, oder nicht je nach dem ob man sich schon im Verzeichnis befindet wo man die Datei haben will und man ist schon fast fertig, ein Enter und noch die Eingabe von MySql Password und die gewählte Datenbank ist gedumpt. Simple, Stupide, Einfach. Klar man kann da noch Ewig parameter dran klatschen. Aber fürn einfach Dump reicht das da vollkommen aus.
Und PS. Soll ich euch mal was stecken das würde so sogar unter CMD laufen 😉 man müsste dort nur ins Verzeichnis von MySql Wechseln. Weil er unter windows den dienst so nicht findet ^^ außer man schreibt halt.

C:\>wamp\bin\mysql\mysql5.5.8\bin\mysqldump -u *** -p test > d:\stuff\test.sql

Wer mir nicht glaubt hier ein Auszug des Resultates.

--
-- Table structure for table `test`
--

DROP TABLE IF EXISTS `test`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `test` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `test` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `test`
--

Schade das M$Sql sowas nicht kann, jedenfalls ist mir bis Heute nichts dergleichen begegnet. Mal von der Abartigkeit abgesehen sich Wahllos Speicher zu reservieren und ihn einfach nicht wieder frei zu geben. Frei nach dem Motto könnte ja in x Sekunden nochmal das selbe gefragt werden.

Wer beim Schreiben seiner Datenbank Klassen und Der SQL Statements so etwas nicht berücksichtigt, dass häufig die selben Daten angefragt werden und diese nach x Fragen in Zeitraum y nicht von selbst einfach in Speicher läd. Und dann die Daten nicht einfach wieder ausm Arbeitsspeicher holt.
Sondern ständig die Datenbank beackert, gehört sowie so geschlagen und so.

Noch besser sind natürlich, UNION SELECTS über 17 Tabellen! Und ich scherze hier nicht. Genau das hab ich hier nämlich gehabt. ein UNION SELECT über 17 Tabellen. Diese Abfrage war und ist faktisch Defekt by Design!

Und glaubt nicht das die 17 Tabellen alle was mit einander zu tun hatten. NEIN … der Author wollte sich nur die Abfragen sparren und Alles was man zu einem User hohlen kann in eine Abfrage verfrachten, Um so Zeit zu sparren. Also anstelle die Daten dann zu Laden wenn sie WIRKLICH gebraucht werden, wurde einfach alles bei jedem Seiten Load geladen! Ob es gebraucht wird oder nicht.

Yey und irgendwann haben sie sich dann gewundert warum die Seite zum Laden plötzlich Minuten statt Sekunden braucht.

Kleines Beispiel? Das hier ist natürlich verschleiert 😉 Weil wird derzeit noch so eingesetzt. Aber das tut im Grunde nichts anderes, als festzustellen welche Rolle ein User hat. Herrlich oder?

SELECT
	c.idc, 
	c.co, 
	c.theme,
	p.idp, 
	uRoleM.rn, 
	NULL, 
	NULL,
	ul.urm_id, 
	m2.name, 
	c.KD, 
	c.mV, 
	c.mDD, 
	ISNULL(c.scRscR,1), 
	ISNULL(ul.language,ISNULL(c.defaultLanguage,'de_DE'))
FROM 
	co c, 
	Pr p, 
	UL ul, 
	URM uRoleM, 
	Module m2
WHERE 
		c.idc=p.co_id
	AND p.idp=ul.Pr_id
	AND ul.un=''
	AND m2.id=uRoleM.module_id
	AND ul.urm_id=uRoleM.id_role
UNION
SELECT 
	c.idc, 
	c.co, 
	c.theme, 
	p.idp, 
	uRoleM.rn, 
	ummr.rights,
	m.name,
	ul.urm_id, 
	m2.name,
	c.KD,
	c.mV, 
	c.mDD, 
	ISNULL(c.scR,1),
	ISNULL(ul.language,
	ISNULL(c.defaultLanguage,'de_DE'))
FROM 
	co c, 
	Pr p, 
	UL ul,
	URM uRoleM,
	UserManagementModuleRights ummr, 
	Module m, 
	coModuleRights cmr, 
	Module m2
WHERE 
		c.idc=p.co_id
	AND p.idp=ul.Pr_id
	AND ul.un=''
	AND ul.urm_id=uRoleM.id_role
	AND ummr.role_id=uRoleM.id_role
	AND m.id=ummr.module_id
	AND cmr.module_id=ummr.module_id
	AND c.idc=cmr.co_id
	AND m2.id=uRoleM.module_id
GROUP BY 
	c.idc, 
	c.co, 
	c.theme, 
	p.idp, 
	uRoleM.rn, 
	ummr.rights,
	ul.urm_id, 
	m.name, 
	m2.name,
	c.KD,
	c.mV, 
	c.mDD, 
	c.scR, 
	ul.language, 
	c.defaultLanguage
UNION
SELECT 
	c.idc, 
	c.co, 
	c.theme, 
	p.idp, 
	uRoleM.rn, 
	ummr.rights,
	me.extraName,
	ul.urm_id, 
	m2.name,
	c.KD,
	c.mV, 
	c.mDD, 
	ISNULL(c.scR,1), 
	ISNULL(ul.language,
	ISNULL(c.defaultLanguage,'de_DE'))
FROM 
	co c, 
	Pr p, 
	UL ul,
	URM uRoleM,
	UserManagementModuleRights ummr, 
	ModuleExtra me, 
	coModuleRights cmr, 
	Module m2
WHERE 
		c.idc=p.co_id
	AND p.idp=ul.Pr_id
	AND ul.un=''
	AND ul.urm_id=uRoleM.id_role
	AND ummr.role_id=uRoleM.id_role
	AND ummr.extra_id=me.id
	AND cmr.extra_id=ummr.extra_id
	AND c.idc=cmr.co_id
	AND m2.id=uRoleM.module_id
GROUP BY 
	c.idc, 
	c.co, 
	c.theme,
	p.idp, 
	uRoleM.rn, 
	ummr.rights,
	ul.urm_id, 
	me.extraName, 
	m2.name,
	c.KD,
	c.mV,
	c.mDD, 
	c.scR, 
	ul.language, 
	c.defaultLanguage

BTW. als ich diese Abfrage das erste mal sah, war meine Reaktion. Schmeiß weg die Datenbank und mach neu. Das da ist faktisch Kaputt. Also halten wir fest. Wenn ihr sowas zusammenschreibt, Überdenkt euer Datenbank Design nochmal dringendst! Weil dann ist das nämlich Defekt, vollkommen Defekt!