"Skalierung" von postgres Datenbank

Moin moin,
Ich möchte zuerst eine Statistik von einer Tabelle erheben (sagen wir mal ‘usr’). ‘usr’ enthält mehrere Spalten (id, cusid, archiv, groupid, username, pwd etc.). Jetzt möchte ich herausfinden wieviel Prozent der id’s die cusid 1234 haben usw. Also z.B. :
id cusid archiv groupid
1 1234 true 34623
2 1233 true 34826
3 1234 true 36985
4 1112 true 38471
5 1112 true 39786

Anteil: 1234 = 40%; 1233 = 20%; 1112 = 40%;

Anhand dieser Angaben möchte ich dann meine Datenbank skalieren, also wenn ich mir neue Daten generiere soll der prozentuale Anteil immernoch gleich sein ! Also:
id cusid archiv groupid
1 1234 true 34623
2 1233 true 34826
3 1234 true 36985
4 1112 true 38471
5 1112 true 39786
6 1234 true 32633
7 1233 true 34116
8 1234 true 39992
9 1112 true 34471
10 1112 true 33726

Gibt es ein Tool, das mir solche Statistik liefert ? Oder sogar, eines, das genau das erledigt (also analysieren und anhand der Ergebnis auf n Einträge aufstocken) ?

Gruß mtsB

Nun, um die Verteilung zu berechnen reicht SQL:

test=# select * from statistik;
 id | cusid |       value       
----+-------+-------------------
  1 |  1234 | 0.158590145409107 
  2 |  1233 | 0.970524633768946 
  3 |  1234 | 0.441964090336114 
  4 |  1112 |  0.73335548909381 
  5 |  1112 | 0.167339093983173 
(5 rows)                        

Time: 0,172 ms
test=*# with alle as (select count(*) as anzahl from statistik) select cusid,  100*(count(*)::numeric / alle.anzahl)::numeric(5,2) as prozent from statistik, alle group by cusid, alle.anzahl;
 cusid | prozent
-------+---------
  1112 |   40.00
  1233 |   20.00
  1234 |   40.00
(3 rows)

Um nun Datensätze einzufügen, reicht eine kleine Precedure:

test=*# create or replace function scale() returns int as $$declare r record; sql text; begin for r in select * from prozent loop sql = 'insert into statistik (cusid, value) select * from (select ' || r.cusid || ',random() from generate_series(0, ' || r.prozent::int || ') s) foo'; raise notice '%', sql; execute sql; end loop; return 1;end; $$ language plpgsql;
CREATE FUNCTION
Time: 17,432 ms
test=*# select * from scale();
NOTICE:  insert into statistik (cusid, value) select * from (select 1112,random() from generate_series(0, 40) s) foo
NOTICE:  insert into statistik (cusid, value) select * from (select 1234,random() from generate_series(0, 40) s) foo
NOTICE:  insert into statistik (cusid, value) select * from (select 1233,random() from generate_series(0, 20) s) foo
 scale
-------
     1
(1 row)

Time: 1,536 ms
test=*# select count(1) from statistik;
 count
-------
   108
(1 row)

Time: 0,259 ms
test=*# with alle as (select count(*) as anzahl from statistik) select cusid,  100*(count(*)::numeric / alle.anzahl)::numeric(5,2) as prozent from statistik, alle groupby cusid, alle.anzahl;
 cusid | prozent
-------+---------
  1112 |   40.00
  1234 |   40.00
  1233 |   20.00
(3 rows)

Reicht das? Die Berechnung, wie viele Datensätze erzeugt werden, kannst ja anpassen, z.B. mit einem Multiplikator auf prozent.


Andreas

Ach ja, ich vergaß:

ich habe einen VIEW angelegt:

create view prozent as (with alle as (select count(*) as anzahl from statistik) select cusid,  100*(count(*)::numeric / alle.anzahl)::numeric(5,2) as prozent from statistik, alle group by cusid, alle.anzahl);

den ich dann in der Funktion genutzt habe.

Andreas

Danke, das sieht auf jedenfall schon gut aus !
Das mit der Statistik ist schonmal sehr gut. Eine Frage dazu hätte ich noch allerdings, wie kann ich auf- bzw abrunden, auf sagen wir mal 2 Nachkommastellen ?

[font=System]
[/font][LEFT][INDENT][font=Courier New]cusid  | cnt | prozent[/font]
[font=Courier New]-------+-----+-----------------[/font]
[font=Courier New]-20000 | 9   | 16.9811320754717[/font]
[font=Courier New] 47106  | 1   | 1.88679245283019[/font]
[font=Courier New] 31465  | 1   | 1.88679245283019[/font]
[font=Courier New] 29941  | 1   | 1.88679245283019[/font]
[font=Courier New] 34525  | 1   | 1.88679245283019[/font]
[font=Courier New] 51650  | 1   | 1.88679245283019[/font]
[font=Courier New] 44604  | 1   | 1.88679245283019[/font]
[font=Courier New] 21955  | 1   | 1.88679245283019[/font]
[font=Courier New] -30000 | 16  | 30.188679245283[/font]
[font=Courier New] 32990  | 1   | 1.88679245283019[/font]
[font=Courier New] 53591  | 1   | 1.88679245283019[/font]
[font=Courier New] -10000 | 17  | 32.0754716981132[/font]
[font=Courier New] 28415  | 1   | 1.88679245283019[/font]
[font=Courier New] 43047  | 1   | 1.88679245283019[/font]
[/INDENT][/LEFT]

Zum datengenerierung:
Gibt es vllt einen geschmeidiegeren Weg mir Datensätze generieren zu lassen? Kennst du da vllt ein Tool ?

Btw: wie hast du die Tabelle so hinbekommen ? Hab mich mal daran versucht, bin gescheitert…

Aah, wie ich gerade sehe, hast du das ja schon gemacht (runden). Hab das übersehen.
Also gehts nurnoch um die Generierung. Meine Tabelle besteht aus 16 Spalten, ich glaub das geht mit nem Tool einfacher, kennste da eins ?

Gruß

Ja. $EDITOR.

Andreas