Ich bin neu in MySQL und ich habe viele Post-Talking-Transaktionen und Tabellensperren gelesen, die ich hier und über das Netz gefunden habe, also denke ich, dass meine Frage nicht redundant sein sollte.MySQL Transaktion VS Table Lock für Benutzerregistrierung
Ich versuche, Abfragen zu optimieren, vor allem für Benutzerregistrierung und Sitzungen. Die Webanwendung ist in PHP/MySQL (i) geschrieben und ich verwende InnoDB Engine.
Ich benutze $ _SESSIONS nicht, um Benutzersitzungen zu speichern, aber ich benutze eine Tabelle auf DB, in der ich einige Informationen über die Benutzersitzung speicher, die mit Plätzchen lebendig gehalten wird. Diese Methode erfordert, dass ich die Benutzersitzung in der DB für jede Benutzerseitenanforderung überprüfe. Dadurch schließe ich mich auch der "users" -Tabelle in der Select-Session-Abfrage an, um jedes Mal neue Benutzerinformationen zu erhalten.
Auf Benutzerregistrierung Anfragen bin ich nicht sicher, was Methode ist besser für: Performance, Codequalität und Sicherheit Probleme zu vermeiden, wenn mehr als ein Benutzer versuchen, die gleichen Benutzername/E-Mail zur gleichen Zeit zu registrieren.
Benutzer Tabelle:
user_id (primary, AI)
username (unique)
email (unique)
password
field 1
field 2
...
Wenn Abfrage schlägt fehl, da der Benutzername oder E-Mail bereits Ich muss wissen genommen wird, zu dem man bereits vergeben ist.
VERFAHREN: LOCK Benutzer TABLE
LOCK TABLES users WRITE;
// users provided username and email are already taken?
SELECT COUNT(username) username, (SELECT COUNT(email) FROM users WHERE email = '[email protected]') email FROM users WHERE username = 'batman'
$res = fetch_array;
if($res['username'] == 0 && $res['email'] == 0){
INSERT INTO users (username,email,password) VALUES ('batman','[email protected]','imtheonlytruehero')
if(affected_rows == 1)
$username = null;
$email= null;
$registration = true;
}
else {
$username = null;
$email= null;
$registration = false;
}
}
else {
$username = ($res['username'] > 0) ? false : true;
$email = ($res['email'] > 0) ? false : true;
$registration = false;
}
UNLOCK TABLES;
METHODE B: TRANSACTION mit INSERT + UPDATE
START TRANSACTION;
INSERT INTO users (username,email,password) VALUES ('batman','0','imtheonlytruehero');
if(affected_rows > 0) {
$username = true;
UPDATE users SET email='[email protected]' WHERE username='batman';
if(affected_rows > 0) {
$email = true;
$registration = true;
COMMIT;
}
else {
$email = false;
$registration = true;
ROLLBACK;
}
}
else {
$username = false;
$email = null;
$registration = false;
ROLLBACK;
}
Meine Sorge Methode A verwendet, ist: Was ist mit anderen protokollierten geschieht Benutzer (unter der Annahme, dass sie viel sind), wenn sie versuchen, ihre Sitzungen für die Navigation verifiziert zu bekommen (erinnern Sie sich an "Sitzungsüberprüfung", schließen Sie sich auch der Benutzertabelle an) whe n Ein neuer Benutzer registriert sich und seine Abfrage sperrt die Benutzertabelle? Langsamkeit? Zeitüberschreitungen? Oder sind die Abfragen (auswählen und einfügen) leicht genug, um die Leistung nicht zu beeinträchtigen?
Hat Methode B hohe Chancen, Deadlocks zu generieren?
Was kann ich tun? Wählen Sie eine dieser Methoden? Mischen sie? Trashing alles und neu anfangen?
Ich schätze jede Hilfe. Danke.
Was Sie wirklich nur einen eindeutigen Index tun sollte, ist, setzen auf den Benutzernamen und E-Mails. Dann können Sie überhaupt keine Duplikate haben, und die Datenbank übernimmt das für Sie. Transaktionen werden keine doppelten Werte blockieren, und die Sperrung würde wahrscheinlich funktionieren, könnte aber Probleme verursachen, wenn nichts getan werden kann, während die Tabelle gesperrt ist, was die Leistung beeinträchtigt. Ein eindeutiger Index würde doppelte Zeilen verhindern und kann als Ausnahme abgefangen werden. –
Danke für Ihre Antwort. Ich habe bereits einen eindeutigen Index für den Benutzernamen und die E-Mail-Spalten festgelegt, wie am Anfang des Beitrags erwähnt. Mein Zweifel ist jedoch, wenn ich nur die Einfügung und ein Benutzer benutze sowohl Benutzernamen und E-Mail bereits auf der Tabelle gesetzt kann ich ihm nicht sagen, wenn beide genommen werden, weil mysql Fehlerbericht nur der erste doppelte Schlüssel aufgetreten ist, so dass ich in diesem Fall kann Ich weiß nicht, ob auch die E-Mail bereits verwendet wird, was dazu führt, dass der Benutzer eine andere Einfügung versucht, um zu wissen, dass auch die E-Mail genommen wurde. Kennen Sie irgendeine Methode, um sich diesem "Problem" zu stellen? Vielen Dank! – cicciopast
Abfrage, um zu sehen, ob entweder bereits in der Datenbank vorhanden sind. dann kannst du ihnen sagen, dass sie benutzt werden. Der eindeutige Index ist nur dazu da, um sicherzustellen, dass es keine Duplikate gibt. nichts anderes. Sie sollten im Voraus überprüfen, ob es benutzerfreundlicher ist und sich nicht auf den Datenbankindex verlässt, um die Fehler zu erkennen. Sie sind ein Sicherheitsnetz. –