SQL 2 Varianten Welche ist sinnvoller?

Dein Thema passt einfach in kein Forum? Dann probiers mal hier.
Nvidia
Beiträge: 238
Registriert: 22. Februar 2010 21:23

SQL 2 Varianten Welche ist sinnvoller?

Beitrag von Nvidia »

Ich für ein Problem zwei Varianten, welche ist sinnvoller?
Kleines Beispiel:
Ich habe 100 Personen. (a 10 Personen in 10 Gruppen).
Variante a):
ich erstelle einen Table mit den Gruppenamen und eine Tabelle mit dem Personen, wobei eine Spalte den Gruppennamen trägt.
2 Tables erstellen. Fertig.
Beim Auslesen einer Gruppe, müsste er ~ 100x vergleichen und einlesen.
Variante b)
ich erstelle einen Table mit den Gruppenamen und für jeden Gruppennamen eine eigenen Table.
Beim Auslesen einer Gruppe, müsste er ~10x einlesen. Das vergleichen, fiele dann weg.
Allerdings habe ich einige Tabellen mehr. Bei dieser Größenordnung spielt das keine Rolle ist nur ein Beispiel.
Welche ist sinnvoller?
nvidia
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Variante a)
Variante b macht man nicht, außer über Partionierung.
Nvidia
Beiträge: 238
Registriert: 22. Februar 2010 21:23

Beitrag von Nvidia »

warum
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Jein zu a). Nicht den Gruppenname sondern die ID der jeweiligen Gruppe solltest du eintragen. Das kann böse enden, wenn du mal eine Gruppe umbenennen willst und dann auch noch alle alten Einträge aus der "Personen"-Tabelle ändern darfst.

Häufig (dann wenn du nicht nur diese viele-zu-eine-Verknüpfung hast) nimmt man auch eine eigene Lookup-Tabelle für die Verknüpfungen. In der werden dann jeweils die ID der Gruppe und die der Person in einer Reihe eingetragen. Solltest du später noch andere Gruppierungen deiner Personen einfügen wollen, ist das so einfacher zu handhaben.
FaS
Beiträge: 184
Registriert: 25. Mai 2006 19:48
Kontaktdaten:

Beitrag von FaS »

Und wenn du die Gruppen-Spalte in der Personen-Tabelle indizierst, muss die SQL-Engine auch nicht 100 Einträge durchgehen, um alle Personen einer bestimmten Gruppe zu liefern.
Gruß,
FaS
Nvidia
Beiträge: 238
Registriert: 22. Februar 2010 21:23

Beitrag von Nvidia »

ok ich hab das jetzt versucht an einem beispiel mit dem primery key, aber das haut nicht so ganz hin.

Code: Alles auswählen

#include "mainwindow.h"

#include <QtGui>
#include <QtSql>


MainWindow::MainWindow()
{

    w = new QWidget;
    button = new QPushButton;
    button->setText("Push me");
    line = new QLineEdit;
    show2 = new QLabel;
    connect(button,SIGNAL(clicked()),this,SLOT(Methode1()));

    QHBoxLayout *layout2 = new QHBoxLayout;
    layout2->addWidget(line);
    layout2->addWidget(button);
    layout2->addWidget(show2);
    w->setLayout(layout2);

    setCentralWidget(w);
}


void MainWindow::Methode1()
{
    QString k = line->text();
    QSqlQuery query("INSERT into person (name)"
                    "VALUES ("+line->text()+")");
    query.exec();

    QSqlQuery query2("SELECT last_insert_rowid();");
    QString k2 = query2.value(0).toString();
    show2->setText(k2);
}


Ich erhalte als Antwort QSqlQuery::value: not positioned on a valid record.
ich hab ein bisschen mit dem record rumprobiert, aber ich erhalte immer als ergebnis -1. was ja nicht sein kann
FaS
Beiträge: 184
Registriert: 25. Mai 2006 19:48
Kontaktdaten:

Beitrag von FaS »

Du executest dein 2. Query garnicht.
Und nebenbei erwähnt, gibt es QSqlQuery::lastInsertId().
Gruß,
FaS
Nvidia
Beiträge: 238
Registriert: 22. Februar 2010 21:23

Beitrag von Nvidia »

ok das hat mich auch gewundert. Weil unter diesem Beispiel
http://doc.trolltech.com/4.6/qsqlquery.html
QSqlQuery query("SELECT country FROM artist");
while (query.next()) {
QString country = query.value(0).toString();
doSomething(country);
}
wird er auch nicht executed.
ok ich versuchs mal damit.
also so sieht das nun aus:

Code: Alles auswählen

void MainWindow::Methode1()
{
    QString k = line->text();
    QSqlQuery query("INSERT into person (name)"
                    "VALUES ("+k+")");

    query.exec();
    QString k2 = query.lastInsertId().toString();
    qDebug() << query.lastError();
    show2->setText(k2);
}
Als Fehler meint er QSqlError(-1,"Unable to fetch row","no query");
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Doch, die 2. Query wird schon ausgeführt. Die 1. wird sogar 2x ausgeführt.

Nur wenn man ein Ergebnis will, sollte man den Datenzeiger auch positionieren. Z.B. mit next().
FaS
Beiträge: 184
Registriert: 25. Mai 2006 19:48
Kontaktdaten:

Beitrag von FaS »

Sorry du hast Recht:
Konstruktor-mit-Query-String-Doku hat geschrieben:[...] If query is not an empty string, it will be executed. [...]
Das heißt dein 1. exec() ist auch überflüssig bzw. fügt deine Person ein zweites Mal hinzu.
Dann fehlt jetzt nur noch query2.next(), wie im Beispiel ;-)
Nvidia
Beiträge: 238
Registriert: 22. Februar 2010 21:23

Beitrag von Nvidia »

???
Wozu und wo brauch ich nun next()?
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Versuch einfach mal die Doku zu lesen.
Nvidia
Beiträge: 238
Registriert: 22. Februar 2010 21:23

Beitrag von Nvidia »

check das nicht, wofür ich nun next brauch.
ich weiß, dass bei next() er die tabelle immer weiter durch geht.
Aber wofür brauch ich das denn?
Wenn ich doch grat was eingefügt habe und dannach die letzte Id abfrage, warum muss ich dann next aufrufen?!
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

bool QSqlQuery::next ()
Retrieves the next record in the result, if available, and positions the query on the retrieved record. Note that the result must be in the active state and isSelect() must return true before calling this function or it will do nothing and return false.
The following rules apply:
If the result is currently located before the first record, e.g. immediately after a query is executed, an attempt is made to retrieve the first record.
If the result is currently located after the last record, there is no change and false is returned.
If the result is located somewhere in the middle, an attempt is made to retrieve the next record.
If the record could not be retrieved, the result is positioned after the last record and false is returned. If the record is successfully retrieved, true is returned.
Was ist daran nicht verständlich?
Nvidia
Beiträge: 238
Registriert: 22. Februar 2010 21:23

Beitrag von Nvidia »

Code: Alles auswählen

void MainWindow::Methode1()
{
    QString k = line->text();
    QSqlQuery query("INSERT into person (name)"
                    "VALUES ("+line->text()+")");
    while (query.next())
    {
    QString k2 = query.lastInsertId().toString();
    show2->setText(k2);
    }
}
Da krieg ich einen leeren String.
Antworten