Latar Belakang:
Saya merancang aplikasi server dan membuat dll terpisah untuk berbagai subsistem. Untuk menyederhanakan banyak hal, katakanlah saya memiliki dua subsistem: 1) Users
2)Projects
Antarmuka publik pengguna memiliki metode seperti:
IEnumerable<User> GetUser(int id);
Dan antarmuka publik Projects memiliki metode seperti:
IEnumerable<User> GetProjectUsers(int projectId);
Jadi, misalnya, ketika kita perlu menampilkan pengguna untuk proyek tertentu, kita dapat memanggil GetProjectUsers
dan itu akan memberikan kembali objek dengan info yang cukup untuk ditampilkan dalam datagrid atau serupa.
Masalah:
Idealnya, Projects
subsistem seharusnya tidak juga menyimpan informasi pengguna dan itu hanya harus menyimpan Id dari pengguna yang berpartisipasi dalam suatu proyek. Dalam rangka untuk melayani GetProjectUsers
, perlu untuk memanggil GetUser
dari Users
sistem untuk setiap user id disimpan dalam database sendiri. Namun, ini membutuhkan banyak GetUser
panggilan terpisah , menyebabkan banyak permintaan sql terpisah di dalam User
subsistem. Saya belum benar-benar menguji ini tetapi memiliki desain cerewet ini akan mempengaruhi skalabilitas sistem.
Jika saya mengesampingkan pemisahan subsistem, saya bisa menyimpan semua info dalam skema tunggal yang dapat diakses oleh kedua sistem dan Projects
hanya bisa melakukan JOIN
untuk mendapatkan semua pengguna proyek dalam satu permintaan tunggal. Projects
juga perlu tahu cara menghasilkan User
objek dari hasil permintaan. Tetapi ini mematahkan pemisahan yang memiliki banyak keuntungan.
Pertanyaan:
Adakah yang bisa menyarankan cara untuk menjaga pemisahan sambil menghindari semua GetUser
panggilan individu ini selama GetProjectUsers
?
Misalnya, satu ide yang saya miliki adalah agar Pengguna memberikan kemampuan sistem eksternal untuk "menandai" pengguna dengan pasangan nilai-label, dan untuk meminta pengguna dengan nilai tertentu, misalnya:
void AddUserTag(int userId, string tag, string value);
IEnumerable<User> GetUsersByTag(string tag, string value);
Kemudian sistem Proyek dapat menandai setiap pengguna saat ditambahkan ke proyek:
AddUserTag(userId,"project id", myProjectId.ToString());
dan selama GetProjectUsers, ini dapat meminta semua pengguna proyek dalam satu panggilan:
var projectUsers = usersService.GetUsersByTag("project id", myProjectId.ToString());
bagian yang saya tidak yakin tentang ini adalah: ya, Pengguna adalah agnostik proyek tetapi sebenarnya informasi tentang keanggotaan proyek disimpan dalam sistem Pengguna, bukan Proyek. Aku hanya merasa tidak alami jadi aku mencoba untuk menentukan apakah ada kerugian besar di sini bahwa aku hilang.
sumber
GetUser
alih-alih menanyakan database, akan mencari dalam cache. Ini berarti bahwa sebenarnya tidak masalah berapa kali Anda akan meneleponGetUser
, karena itu akan memuat data dari memori daripada database (kecuali cache sudah tidak valid).select
permintaan per hari, Anda sebaiknya menggunakan caching. Di sisi lain, jika Anda menambahkan miliaran entitas ke dalam basis data tetapi hanya mendapatkan beberapa ribu entitasselect
dengan selektif yang sangatwhere
, caching mungkin tidak bermanfaat.