MySQL: Grad der Vollständigkeit

port29

deus.Server
Hallo Leute,

ich habe heute eine Frage an Euch. Ich suche nach einer möglichst einfachen Möglichkeit um festzustellen, wie viele Informationen in einer Tabelle zu einem Datensatz vorhanden sind. Um das nochmal etwas einfacher zu erklären, in einer Tabelle sind Profilangaben von Benutzern gespeichert. In jeder Spalte steht eine Angabe. Ich möchte nun die Profile sehen, die am Wenigsten ausgefüllt haben.

Gibt es da eine saubere Möglichkeit? Mir fällt gerade nur die Brute Force Methode ein, wo ich jedes Feld angebe und einzeln überprüfe.
 
Hmm ja da fällt mir auch nichts anderes ein als vielleicht eine Stored Procedure die das Datenbankseitig macht.

Allerdings spricht das nicht für gutes Design wenn du sowas vorhast. Da wäre doch eine Repräsentation einer Tabelle
User Attribut Wert
sinnvoller gewesen. Dann könnte man das ohne Probleme mit eine SELECT Statement rausfinden.
 
Allerdings spricht das nicht für gutes Design wenn du sowas vorhast. Da wäre doch eine Repräsentation einer Tabelle
User Attribut Wert
sinnvoller gewesen. Dann könnte man das ohne Probleme mit eine SELECT Statement rausfinden.

Naja, das von dir vorgeschlagene Design finde ich aber auch nicht ganz doll und zwar aus zwei Gründen:

1) Wenn ich 40 Attribute speichere, dann sind es bei 100.000 Benutzern schon rund 4Mio Datensätze, bei denen ich 1/3 der Daten mehrfach in der DB halten muss. (Die Attribute sind bei allen Usern gleich).

2) Bin ich mit der gleichen Masche schonmal fürchterlich auf die Nase gefallen. Ich habe ein Shopsystem geschrieben, dass die Artikel Features genau auf die gleiche Weise gespeichert hat. Hatte den Vorteil, dass man zu verschiedenen Artikelkategorien auch verschiedene Daten ablegen kann. Auf dem Papier sah das ganze ganz gut aus, aber die Praxis war doch etwas schwieriger. Da ich die Daten alle auf einmal abfragen wollte, kamen Kilometerlange Joins heraus. Ok, ich dachte mir, dass ich einmal die Arbeit gemacht habe und die Joins nun so stimmen. Tja nur habe ich das falsch gedacht. Denn MySQL hat sich an den Joins gelegentlich fürchterlich verschluckt. Was normalerweise nur bruchteile einer Sekunde gedauert hat, dauerte ab und zu bis zu 15 Minuten!

http://bugs.mysql.com/bug.php?id=26339

Deshalb werde ich in nächster Zeit kein solches Design aufbauen.
 
Ja das kann durchaus sein dass das auch nicht optimal ist ;)

Sonst mach halt nen
SQL:
SELECT 
     COUNT(CASE WHEN column1 IS NULL THEN 1 ELSE NULL END)+ 
     COUNT(CASE WHEN column2 IS NULL THEN 1 ELSE NULL END) AS emptyColumns
FROM UserProfile;

Dann mußt du nur immer dran denken alle Spalte zu inkludieren. Ich kenn mich mit Stored Procedures nicht aus, aber das wäre vielleicht einfacher.
 
1) Wenn ich 40 Attribute speichere, dann sind es bei 100.000 Benutzern schon rund 4Mio Datensätze, bei denen ich 1/3 der Daten mehrfach in der DB halten muss. (Die Attribute sind bei allen Usern gleich).
Welche Werte müsstest du denn mehrfach halten?

[…] Da ich die Daten alle auf einmal abfragen wollte, kamen Kilometerlange Joins heraus.
Ich hätte mir da die Joins gespart und stattdessen zwei Abfragen verwendet. Zum ersten
SQL:
SELECT artikel_id, titel, preis FROM artikel WHERE artikel_id = 123
und zum zweiten
SQL:
SELECT vorlage_item_id, wert FROM features WHERE artikel_id = 123
Das Herausziehen der einzelnen Attribute aus dem Ergebnis der zweiten Abfrage hätte ich dann im Programm implementiert.

Sonst mach halt nen
SQL:
SELECT 
     COUNT(CASE WHEN column1 IS NULL THEN 1 ELSE NULL END)+ 
     COUNT(CASE WHEN column2 IS NULL THEN 1 ELSE NULL END) AS emptyColumns
FROM UserProfile;
Geht auch noch etwas kürzer:
SQL:
SELECT 
     COUNT(column1)+ 
     COUNT(column2) AS emptyColumns
FROM UserProfile
GROUP BY user_id;

Grüße,
Matthias
 
Zurück