Berikut ini adalah bagaimana saya akan melakukannya. Saya memiliki beberapa komentar lagi di bagian bawah setelah Anda melihat skemanya.
Masuk
LogID - ID log unik
Waktu - tanggal/waktu acara
LogType - String atau ID
(komentar sampingan, saya akan menggunakan id di sini sehingga Anda dapat menggunakan tabel pesan yang ditunjukkan di bawah ini, tetapi jika Anda ingin cepat dan kotor, Anda hanya dapat menggunakan string unik untuk setiap waktu log (mis. "Permainan Dimulai", "Pesan Terkirim" , dll)
Aktor Log
LogID - kunci eksternal
LogActorType - String atau ID (seperti di atas, jika ID Anda memerlukan tabel pencarian)
LogActorID - Ini adalah id unik untuk tabel untuk jenis misalnya Pengguna, Grup, Game
Urutan - ini adalah urutan aktor.
Pesan Log
LogType - kunci eksternal
Pesan - string panjang (varchar(maks)?)
Bahasa - string(5) sehingga Anda dapat memasukkan bahasa yang berbeda misalnya "US-en"
Contoh Data(menggunakan 3 contoh Anda)
Masuk
ID Time LogType
1 1/1/10 1
2 1/1/10 2
3 1/1/10 3
LogActor
LogID LogActorType LogActorID Sequence
1 User 1 1
1 User 2 2
2 User 1 1
2 User 2 2
2 User 2 3
2 Game 1 4
3 User 3 1
3 Group 1 2
Pesan Log
LogType Message
1 {0} Made a new friend {1}
2 {0}, {1}, {2} played a game ({3})
3 {0} joined a group ({1})
Pengguna
ID Name
1 User A
2 User B
3 User C
Permainan
ID Name
1 Name of game
Grup
ID Name
1 Name of group
Jadi, inilah hal-hal baik tentang desain ini.
-
Sangat mudah untuk memperpanjang
-
Ini menangani masalah multi-bahasa terlepas dari aktornya
-
Ini mendokumentasikan diri sendiri, tabelLogMessage menjelaskan dengan tepat apa yang seharusnya dikatakan oleh data yang Anda simpan.
Beberapa hal buruk tentangnya.
-
Anda harus melakukan beberapa pemrosesan yang rumit untuk membaca pesan.
-
Anda tidak bisa hanya melihat DB dan melihat apa yang telah terjadi.
Dalam pengalaman saya, bagian bagus dari desain semacam ini lebih banyak daripada bagian buruknya. Apa yang telah saya lakukan untuk memungkinkan saya melihat log dengan cepat dan kotor adalah membuat tampilan (yang tidak saya gunakan untuk kode aplikasi) yang dapat saya lihat ketika saya perlu melihat apa yang terjadi melalui bagian belakang akhir.
Beri tahu saya jika Anda memiliki pertanyaan.
Pembaruan - Beberapa contoh kueri
Semua contoh saya ada di sqlserver 2005+, beri tahu saya jika ada versi lain yang Anda ingin saya targetkan.
Lihat tabel LogActor(Ada beberapa cara untuk melakukan ini, yang terbaik tergantung pada banyak hal termasuk distribusi data, kasus penggunaan, dll)Berikut adalah dua:
a)
SELECT
LogId,
COLLESCE(U.Name,Ga.Name,Go.Name) AS Name,
Sequence
FROM LogActor A
LEFT JOIN User U ON A.LogActorID = U.[ID] AND LogActorType = "User"
LEFT JOIN Game Ga ON A.LogActorID = Ga.[ID] AND LogActorType = "Game"
LEFT JOIN Group Go ON A.LogActorID = Go.[ID] AND LogActorType = "Group"
ORDER BY LogID, Sequence
b)
SELECT
LogId,
U.Name AS Name,
Sequence
FROM LogActor A
INNER JOIN User U ON A.LogActorID = U.[ID] AND LogActorType = "User"
UNION ALL
SELECT
LogId,
Ga.Name AS Name,
Sequence
FROM LogActor A
INNER JOIN Game Ga ON A.LogActorID = Ga.[ID] AND LogActorType = "Game"
UNION ALL
SELECT
LogId,
Go.Name AS Name,
Sequence
FROM LogActor A
INNER JOIN Group Go ON A.LogActorID = Go.[ID] AND LogActorType = "Group"
ORDER BY LogID, Sequence
Secara umum saya pikir a) lebih baik daripada b) Misalnya jika Anda kehilangan tipe aktor a) akan memasukkannya (dengan nama nol). Namun b) lebih mudah untuk dipelihara (karena pernyataan UNION ALL membuatnya lebih modular.) Ada cara lain untuk melakukan ini (misalnya CTE, view, dll). Saya cenderung melakukannya seperti b) dan dari apa yang saya lihat, tampaknya itu setidaknya praktik standar jika bukan praktik terbaik.
Jadi, 10 item terakhir di log akan terlihat seperti ini:
SELECT
LogId,
M.Message,
COLLESCE(U.Name,Ga.Name,Go.Name) AS Name,
Time,
A.Sequence
FROM Log
LEFT JOIN LogActor A ON Log.LogID = A.LogID
LEFT JOIN User U ON A.LogActorID = U.[ID] AND LogActorType = "User"
LEFT JOIN Game Ga ON A.LogActorID = Ga.[ID] AND LogActorType = "Game"
LEFT JOIN Group Go ON A.LogActorID = Go.[ID] AND LogActorType = "Group"
LEFT JOIN LogMessage M ON Log.LogType = M.LogMessage
WHERE LogID IN (SELECT Top 10 LogID FROM Log ORDER BY Date DESC)
ORDER BY Date, LogID, A.Sequence
NB - Seperti yang Anda lihat, lebih mudah untuk memilih semua item log dari tanggal daripada X terakhir, karena kami memerlukan sub-kueri (mungkin sangat cepat) untuk ini.