1) Definetely ja, sollte ids sein auto-autoinkrementierten, wenn Sie ein anderes Mittel eines Primärschlüssels zur Verfügung stellen Das ist einzigartig. Sie erhalten die ID des Einsatzes entweder mit mysql_insert_id()
oder LAST_INSERT_ID()
von mysql direkt, also einige angeschlossenen Infos posten Sie entweder
mysql_query("INSERT INTO table1 ...")
$foreign_key=mysql_insert_id(); //this gives you the last auto-increment for YOUR connection
tun können, oder, aber nur, wenn Sie absolut sicher, dass niemand sonst in der Tabelle schreibt in der Zwischenzeit oder hat die Kontrolle über die Transaktion, nachdem Einsatz tun:
$foreign_key=mysql_query("SELECT LAST_INSERT_ID()")
INSERT INTO table2 message_id=$foreign_key
oder ohne den FK zu php zu ziehen, die alle in einer Transaktion (I Beratung auch die SQL als eine Transaktion zu wickeln) mit etwas wie:
"INSERT INTO table1...; INSERT INTO table2 (message_id,...) VALUES(LAST_INSERT_ID(),...)"
Abhängig von Ihrer Sprach- und MySQL-Bibliothek können Sie möglicherweise den Multi-Query-Ansatz nicht ausführen. Daher ist es besser, den ersten Ansatz zu verwenden.
2) Dies kann so viele Ansätze haben, je nachdem, ob Sie auch auf alle Empfänger antworten müssen (z. B. Konferenz), in einer Thread-/Forum-ähnlichen Weise antworten, ob die Clientseite den zuletzt abgerufenen Inhalt speichern kann Nachricht/ID (zB in einem Cookie; auch davon betroffen, ob Sie wirklich das "Lesen" -Feld benötigen). Der "private Chat" -Ansatz ist der einfachste, Sie sind wahrscheinlich besser dran, entweder die Nachricht in einer Tabelle zu speichern und die von-zu-Beziehungen in eine andere (und verwenden Sie JOINs auf ihnen) oder einfach wieder aufzufüllen die Nachricht in einer Tabelle (seit Speicher ist heutzutage billig). So würde die vereinfachte Modell eine Tabelle sein:
table: message_body,from,to
$recepients=array(1,2,3..);
foreach($recepients as $recepient)
mysql_query("INSERT INTO table (...,message_body,from,to) VALUES(...,$from,$recepient)");
(Duplikat der Nachricht usw., nur die Recepient Änderungen)
oder
message_table: id,when,message_body
to-from-table: id,msg_id,from,to
$recepients=array(1,2,3,...);
mysql_insert("INSERT INTO message_table (when,message_body) VALUES(NOW(),$body)");
$msg_id=mysql_insert_id();
foreach($recepients as $recepient)
mysql_query("INSERT INTO to-from-table (msg_id,from,to) VALUES($msg_id,$from,$recepient)");
(Nachricht einmal eingefügt, speichern Sie die Beziehungen und FK für alle Empfänger)
Jeder Client speichert dann die letzte message_id, die er/sie erhalten hat (standardmäßig 0), und nimmt an, dass alle vorherigen Nachrichten bereits gelesen wurden):
"SELECT * FROM message WHERE from=$user_id OR to=$user_id WHERE $msg_id>$last_msg_id"
oder wir nehmen nur Kenntnis von der letzten Eingabezeit von dem Benutzer und Abfrage alle neue Nachrichten von da an:
"SELECT * FROM message WHERE from=$user_id OR to=$user_id WHERE when>='".date('Y-m-d H:i:s',$last_input_time)."' "
Wenn Sie eine Konferenz- oder Forum-Lauffläche Ähnliches Vorgehen und die Notwendigkeit, zu verfolgen, wer die Nachricht gelesen hat oder nicht, müssen Sie möglicherweise alle beteiligten Benutzer im Auge behalten.
Angenommen, es wird nicht hundert Leute in einer "Multi-User-Konferenz" geben, würde ich mit einer Tabelle für Nachrichten gehen und den "comma-separated and wrapped list" Trick verwende ich viel zum Speichern von Tags.
id autoincrement (again, no need for a separate message id)
your usual: sent_at, title (if you need one), content
sender (int)
recepients (I'd go with varchar or shorter versions of TEXT; whereas TEXT or BLOB gives you unlimited number of users but may have impact on performance)
readers (same as above)
Das Geheimnis für recepients/Leser Feld ist sie durch Kommata getrennte ID-Liste und wickeln Sie es in Kommas wieder aufzufüllen (Ich werde in warum später dulge).
Sie müssten also IDs von Empfängern wieder in einem Array sammeln, z. $ Recepients = array (2,3,5) und ändern Sie Ihre Einlage:
"INSERT INTO table (sent_at,title,content,sender,recepients) VALUES(NOW(),'$title','$content',$sender_id,',".implode(',', $recepients).",')"
Sie erhalten Tabellenzeilen wie
... Absender | empfänger
... 1 | , 2, // Einzelbenutzernachricht
... 1 | , 3,5, // Multi-User-Nachricht
alle Nachrichten für einen Benutzer mit der ID von $ user_id = 2 Sie mit
SELECT * FROM table WHERE sender=$user_id OR INSTR(recepients, ',$user_id,')
Bisher gehen wählen wir die implodierte Liste der recepients gewickelt, z.B. "5,2,3" wird zu ", 5,2,3", und INSTR sagt hier, ob ', 2' irgendwo als Teilstring enthalten ist - da nach '2', ', 2' oder '2 gesucht wird, "könnte Ihnen z. B. falsche Positive geben' 34,56', '1 **, 2 34', '9,45 2, ** 89' dementsprechend - deshalb mussten wir die Liste an erster Stelle einpacken.
Wenn der Benutzer liest/seine/ihre Nachricht erhält, hängen Sie ihre ID in die Liste Lesern wie:
UPDATE table SET readers=CONCAT(',',TRIM(TRAILING ',' FROM readers),',$user_id,') WHERE id=${initial message_id here}
die Ergebnisse:
... Absender | Empfänger | Leser
... 1 | , 2, | , 2,
... 1 | , 3,5, | , 3,5,2,
Oder wir können nun die erste Abfrage Hinzufügen einer Spalte „is_read“ in den Zustand ändern, ob der Benutzer zuvor die Nachricht gelesen oder nicht:
SELECT * FROM table WHERE INSTR(recepients, ',$user_id,'),INSTR(readers, ',$user_id,') AS is_read
sammeln sich die Message-IDs aus das Ergebnis und aktualisieren Sie die "Receipents" -Felder mit einem einzigen Schritt
"UPDATE table SET readers=CONCAT(',',TRIM(TRAILING ',' FROM readers),',$user_id,') WHERE id IN (".implode(',' ,$received_msg_ids).")"
Danke für die Antwort, ich mag ein bisschen wie die "verpackte Liste" Trick, jedoch habe ich Eine Frage: Wie würde ich mit dieser Methode auch einen Zeitstempel für den Zeitpunkt erfassen, zu dem eine Nachricht tatsächlich gelesen wurde, also anders als nur "is_read" zu verfolgen, möchte ich auch "when_read" von jedem Empfänger verfolgen. – Dodinas