Die länge einer SQL Datenbank anzeigen lassen

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

Hi,

arbeite mich gerade in die SQLite Datenbankprogrammierung mit Python ein, weshalb ich in dem Gebiet noch nicht wirklich sicher bin.

Ich versuche nun die Länge einer Datenbank zu ermitteln, wie gehe ich da vor?

Vielen Dank

McAce
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Was meinst du mit Länge der Datenbank? Die Größe von Tabellen?

Sebastian
Das Leben ist wie ein Tennisball.
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

Oh sorry ich hätte meine Frage genauer Formulieren müssen.

Ich meine damit die Anzahl der Spalten. Ich habe mir testweise eine Datenbank erstellt in der einfach nur
Wörter mit dem Datum wann sie eingelesen worden sind erstellt.
Jetzt würde ich diese gerne mit einem Zufallsgenerator auslesen lassen.

Da hatte ich gedacht verwende ich random.randint(a,b), wobei a mein Anfang der Tabelle ist also 1
und b dann mein Ende. Nur weiß ich nicht genau wie ich das Ende bestimmen soll da die Datenbank
ja wächst bzw. schrumpft wenn Wörter gelöscht werden.
Ich hoffe das das jetzt ausführlich genug ist.

McAce
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Mal abgesehen davon, dass Datenbanken keine Spalten haben, sondern höchstens die Tabellen in der Datenbank, kannst du mittels

Code: Alles auswählen

select count(*) from Tabelle
die Anzahl der Zeilen einer Tabelle ermitteln. Deinem letzten Absatz nach ist es dass, was du möchtest. Denn ich glaube kaum, dass die Anzahl der Spalten einer Tabelle variabel ist. Und wenn doch, solltest du das dringend ändern ...
BlackJack

@McAce: Die Anzahl der *Spalten* und deren Namen solltest Du schon selber wissen. Das sind nach Deiner Beschreibung ja 2 -- Wort und Datum.

Man kann zwar die Anzahl der Zeilen einer Tabelle ermitteln -- mit der SQL-Funktion `COUNT()` -- aber es gibt AFAIK keinen Standardweg um auf eine bestimmte Zeile über ihre "Zeilennummer" zuzugreifen. Weil es so eine nicht gibt. Wie die Daten letztendlich intern organisiert sind, weiss man ja nicht.

Üblicherweise hat man einen eindeutigen Schlüssel für jeden Datensatz. Die kann man dann alle abfragen, sich zufällig einen daraus aussuchen und dann noch einmal gezielt den dazugehörigen Datensatz abfragen. Der Aufwand lohnt sich allerdings nur, wenn das effizienter ist als einfach alle Daten abzufragen und daraus zufällig einen Satz auszuwählen. Das könnte bei Deinen beiden Spalten der Fall sein.
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

Vielen Dank

klar ich meinte Zeilen :oops:

Werde das gleich direkt mal testen

McAce

Edit

ich habe
sql = "SELECT COUNT(*) FROM wortdb"
row=con.execute(sql)
print row

jetzt erhalte ich die Referenz <sqlite3.Cursor object at 0x842450>

wie bekomme ich denn die Anzahl der Zeilen als String raus?
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

habe es hinbekommen

con.rollback()
cursor.execute('''SELECT count(*) FROM linkdb''')
print cursor.fetchone()
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Sqlite kann dir auch direkt zufaellige Eintraege auswaehlen:

Code: Alles auswählen

SELECT * FROM Tabelle ORDER BY RANDOM() LIMIT 1;
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

oh Vielen Dank für den Hinweis, das ist ja klasse :-))

Ich wollte jetzt ein Funktion schreiben die die doppelten Einträge aus einer Datenbank entfernt, gibt es da auch schon was eingebautes?
Ich frage einfach mal bevor ich mir jetzt was mit einer Lambda-Funktion bastel ;-)

McAce
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

McAce hat geschrieben: Ich wollte jetzt ein Funktion schreiben die die doppelten Einträge aus einer Datenbank entfernt, gibt es da auch schon was eingebautes?
Was ist denn "doppelt"? ;-) Komplett identisch geht nicht, da der Primärschlüssel sich bei jedem Tupel (=Zeilen) ja unterscheidet - was ja auch der Sinn des PK ist.

Ich würde mich auf jeden Fall fragen, wie solche doppelten Einträge überhaupt passieren können. So etwas kann durchaus auf ein schlechtes DB-Design hindeuten. Sollten die Daten aus einem Import stammen, so würde ich versuchen beim Import bereits doppelte Einträge zu filtern.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
noisefloor
User
Beiträge: 4191
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Komplett identisch geht nicht,
Doch, wenn man weder einen PK hat noch 'unique' bei Spalten setzt. Womit wir dann aber wieder beim Thema "schlechtes Design" wären. ;-)

Gruß, noisefloor
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

Nicht falsch verstehen das hat rein experimentellen Wert, also keinen tieferen Sinn außer dem das
ich mich in die Materie einarbeiten möchte ;-)

Also ich lese Worte und das Datum wann die Worte eingelesen worden sind in die Datenbank ein. Was natürlich zur folge hat das viele Worte doppelt in der Datenbank vorkommen, jedoch hat jedes Wort
ein anderes Datum.
Nun versuche ich das Wort mit dem älteren Datum aus der Datenbank zu löschen.

Hoffe das ist nicht zu abstrus :D

McAce
Benutzeravatar
noisefloor
User
Beiträge: 4191
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

geht schon, wäre aber wesentlich einfacher, wenn du einen Primärschlüssel wie z.B. eine eindeutige ID pro Zeile hättest.

Ein mögliche Lösung ist:

- Ein Liste erstellen, in der jedes Wort genau einmal vorkommt
- Darauf basierend eine Liste für jedes Wort erstellen, wo alle Daten zu diesem Wort drin sind, aufsteigend sortiert.
- Darauf basierend alle Daten-Wort Kombination löschen, außer die für's neuste Datum.

Ob das auch mit SQL alleine geht weiß ich gerade nicht... Jedenfalls wäre der entsprechende Query nicht gerade trivial.

Gruß, noisefloor
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

Moin,

Ich habe SELECT DISTINCT mal ausgetestet und es macht das was soll die dopleten Werte beid er Ausgabe unterdrücken, leider würde ich diese unterdrücken Werte gerne aus der Datenbank löschen, ist das irgendwie
möglich.

McAce

@noisefloor guter Ansatz ich würde das aber gerne über die Datenbank realisieren
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

Am Ende soll nur der neueste Eintrag dableiben?
Je nach Datenbank geht das auch direkt mit SQL. Ich weiß aber nicht ob das Standard ist.

Postgresql:

Code: Alles auswählen

postgres@homeserver:/$ psql
Welcome to psql 8.3.14, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help with psql commands
       \g or terminate with semicolon to execute query
       \q to quit

postgres=# \c test
You are now connected to database "test".
test=# CREATE TABLE testt (name VARCHAR, dat DATE);
CREATE TABLE
test=# INSERT INTO testt (name, dat) VALUES ('a', '2011-02-10');
INSERT 0 1
test=# INSERT INTO testt (name, dat) VALUES ('a', '2011-02-11');
INSERT 0 1
test=# INSERT INTO testt (name, dat) VALUES ('a', '2011-02-08');
INSERT 0 1
test=# INSERT INTO testt (name, dat) VALUES ('b', '2011-01-15');
INSERT 0 1
test=# INSERT INTO testt (name, dat) VALUES ('b', '2010-12-31');
INSERT 0 1
test=# SELECT * FROM testt;
 name |    dat     
------+------------
 a    | 2011-02-10
 a    | 2011-02-11
 a    | 2011-02-08
 b    | 2011-01-15
 b    | 2010-12-31
(5 rows)

test=# DELETE FROM testt WHERE (name, dat) NOT IN (SELECT name, MAX(dat) FROM testt GROUP BY name);
DELETE 3
test=# SELECT * FROM testt;
 name |    dat     
------+------------
 a    | 2011-02-11
 b    | 2011-01-15
(2 rows)

test=#   
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

Auch wenn der Beitrag nicht der Letzte war:
McAce hat geschrieben:habe es hinbekommen

con.rollback()
[...]
Das Rollback führt zu einem Zurücksetzen der aktuellen Transaktion und hat nichts mit deinem Schreibvorgang zu tun.
Suche nach BEGIN, COMMIT, ROLLBACK. Evtl. hilft dir auch das hier weiter: http://de.wikipedia.org/wiki/Transaktio ... ormatik%29

Das ist wichtig, wo du doch gerade mit SQL anfängst.

Gruß
Sparrow
Benutzeravatar
noisefloor
User
Beiträge: 4191
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
McAce hat geschrieben: @noisefloor guter Ansatz ich würde das aber gerne über die Datenbank realisieren
Dann solltest du dich mal weitergehend mit SQL und Subqueries beschäftigen. ;-)

Ob das am langen Ende sinnvoll ist, ist eine andere Frage. Eine DB mit dieser Struktur solltest du später nie wirklich einsetzen.

Daher macht es IMHO mehr Sinn, dass du dir eine neue DB aufbaust, eine eine bessere Struktur hat, wie z.B. einen Primary Key.

@sparrow: Mit MySQL sollte das auch gehen, habe es aber nicht getestet...

Gruß, noisefloor
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

noisefloor hat geschrieben:Hallo,
McAce hat geschrieben: @noisefloor guter Ansatz ich würde das aber gerne über die Datenbank realisieren
Dann solltest du dich mal weitergehend mit SQL und Subqueries beschäftigen. ;-)

Ob das am langen Ende sinnvoll ist, ist eine andere Frage. Eine DB mit dieser Struktur solltest du später nie wirklich einsetzen.

Daher macht es IMHO mehr Sinn, dass du dir eine neue DB aufbaust, eine eine bessere Struktur hat, wie z.B. einen Primary Key.
Natürlich hast du recht, ein PK ist für verschiedene Sachen absolut Pflicht.
Mir fällt aber gerade eine möglicher Anwendungszweck ein: Wenn man Daten versioniert (wie zum Beispiel die Text in einem Wiki) und nur eine bestimmte Anzahl veralteter Versionen behalten möchte kann man so ältere Versionen löschen.

Grundsätzlich würde ich so etwas (soweit möglich) direkt von der Datenbank erledigen lassen. Dafür ist sie da. Bevor , womöglich mehrmals, Datensätze mit dem Client ausgetauscht werden lieber eine Abfrage auf den Server. Und den malochen lassen. Dann entfällt schonmal die Übertragung der Tupel an den Client.

Gruß
sparrow
Rainier
User
Beiträge: 19
Registriert: Mittwoch 22. August 2007, 10:03

@BlackJack
BlackJack hat geschrieben:aber es gibt AFAIK keinen Standardweg um auf eine bestimmte Zeile über ihre "Zeilennummer" zuzugreifen. Weil es so eine nicht gibt. Wie die Daten letztendlich intern organisiert sind, weiss man ja nicht.
Ich lasse mir Zeilen über ROWID, welche in SQLite (vielleicht auch in anderen DBs) jeder Tabelle als Pseudo-Spalte zugewiesen wird, anzeigen, damit erspare ich mir eine spezielle ID

Code: Alles auswählen

SELECT * FROM table WHERE ROWID = 5
Zuletzt geändert von Rainier am Donnerstag 10. Februar 2011, 15:54, insgesamt 2-mal geändert.
Antworten