Dalam pendidikan saya, saya telah diberitahu bahwa itu adalah ide yang salah untuk mengekspos kunci primer yang sebenarnya (tidak hanya kunci DB, tetapi semua aksesor utama) kepada pengguna.
Saya selalu menganggapnya sebagai masalah keamanan (karena penyerang dapat mencoba membaca barang bukan milik mereka).
Sekarang saya harus memeriksa apakah pengguna diperbolehkan mengakses, jadi apakah ada alasan berbeda di balik itu?
Juga, karena pengguna saya harus mengakses data, saya harus memiliki kunci publik untuk dunia luar di antara keduanya. Sekarang kunci publik memiliki masalah yang sama dengan kunci primer, bukan?
Sudah ada permintaan contoh tentang mengapa melakukan itu, jadi di sini ada satu. Ingatlah bahwa pertanyaan yang dimaksudkan adalah tentang prinsip itu sendiri tidak hanya jika itu berlaku dalam contoh ini. Jawaban yang membahas situasi lain disambut secara eksplisit.
Aplikasi (Web, Mobile) yang menangani aktivitas, memiliki banyak UI dan setidaknya satu API otomatis untuk komunikasi antar sistem (mis. Departemen akuntansi ingin tahu berapa besar biaya pelanggan berdasarkan apa yang telah dilakukan). Aplikasi memiliki banyak pelanggan sehingga pemisahan data mereka (secara logis, data disimpan dalam DB yang sama) harus dimiliki oleh sistem. Setiap permintaan akan diperiksa validitasnya, apa pun yang terjadi.
Aktivitas granular sangat halus sehingga bersama-sama di beberapa objek kontainer, sebut saja "Tugas".
Tiga usecases:
- Pengguna A ingin mengirim Pengguna B ke beberapa Tugas sehingga ia mengiriminya tautan (HTTP) untuk menyelesaikan Aktivitas di sana.
- Pengguna B harus pergi ke luar gedung sehingga ia membuka Tugas di perangkat selulernya.
- Akuntansi ingin menagih pelanggan untuk Tugas, tetapi menggunakan sistem akuntansi pihak ketiga yang secara otomatis memuat Tugas / Kegiatan dengan beberapa kode yang merujuk pada REST - API Aplikasi
Setiap usecases membutuhkan (atau semakin mudah jika) agen untuk memiliki beberapa pengidentifikasi yang dapat dialamatkan untuk Tugas dan Aktivitas.
ON UPDATE CASCADE
dibuat untuk itu (spesifik mysql?), walaupun jika masalahnya adalah keamanan maka pemeriksaan akses harus di backend dan tidak mempercayai penggunaJawaban:
Persis. Ambil HTTP stateless, yang seharusnya tidak tahu sumber daya apa yang harus diminta: itu memaparkan ID pertanyaan Anda
218306
di URL. Mungkin Anda benar-benar bertanya-tanya apakah pengidentifikasi yang terbuka dapat diprediksi ?Satu-satunya tempat di mana saya mendengar jawaban negatif untuk itu, menggunakan alasan: "Tetapi mereka dapat mengubah ID di URL!" . Jadi mereka menggunakan GUID alih-alih menerapkan otorisasi yang tepat.
Saya bisa membayangkan satu situasi di mana Anda tidak ingin pengidentifikasi Anda dapat diprediksi: pemanenan sumber daya. Jika Anda memiliki situs yang host publik sumber daya tertentu yang lain mungkin menarik dalam, dan Anda meng-host mereka seperti
/images/n.jpg
atau/videos/n.mp4
di manan
saja adalah nomor incrementing, siapa pun yang melihat lalu lintas ke dan dari situs web Anda dapat panen semua sumber daya Anda.Jadi, untuk langsung menjawab pertanyaan Anda: tidak, tidak buruk untuk langsung "mengekspos" pengidentifikasi yang hanya memiliki makna pada program Anda, biasanya bahkan diperlukan agar program Anda berhasil beroperasi.
sumber
Anda tidak boleh mengeksposnya karena orang yang melihatnya akan mulai menggunakannya sebagai 'nomor akun' mereka yang BUKAN. Misalnya, untuk rekening bank saya, saya tahu nomor rekening saya. Saya sudah hafal, saya menggunakannya di telepon dengan layanan pelanggan, saya menggunakannya ketika mengisi formulir untuk bank lain untuk melakukan transfer, untuk dokumen hukum, untuk layanan pembayaran otomatis saya, dll, dll. Saya tidak ingin itu berubah. Kunci utama (untuk akun saya) di sisi lain, saya tidak tahu atau tidak pernah melihat.
Sistem yang menyimpannya berubah selama bertahun-tahun dari satu sistem ke sistem lainnya, melalui penggabungan bank, peningkatan dan penggantian sistem, dll. Dll
. Kunci utama dapat berubah melalui beberapa transformasi ini, jadi jika tidak pernah diekspos, dituliskan atau diingat oleh pengguna biasa yang '
Kunci tanpa makna bisnis sering disebut kunci pengganti dan sering (tetapi tidak selalu) digunakan sebagai kunci utama.
Namun, ini bahkan terjadi secara internal ketika orang membangun antarmuka dan program yang menyalahgunakan dan mengekspos kunci primer dan menjadikannya bagian dari sistem semacam itu alih-alih hanya melakukan satu hal - secara unik mengidentifikasi catatan basis data secara internal. Saya benar-benar belajar hal di atas selama 6 tahun mendukung sistem data warehouse di rumah sakit.
sumber
Karena Primary Key adalah detail implementasi.
Jika Anda memigrasi basis data, kunci utama Anda mungkin berubah karena urutan penyisipan, penghapusan catatan lama ... beberapa alasan berbeda. Jika Anda memigrasikan platform basis data Anda mungkin tidak lagi memiliki kunci primer yang sebenarnya sama sekali. Mengekspos PK di atas lapisan akses data adalah abstraksi yang bocor, dengan semua masalah kopling yang menyertainya.
sumber
Ini adalah jawaban kombinasi dari yang lain (alias. Apa yang telah saya pelajari). Jika Anda merasa ingin memperbaiki yang ini, Anda setidaknya harus memilih salah satu dari yang lain dan mereka melakukan pekerjaan yang sebenarnya. Jika Anda lebih tertarik, baca jawaban lain sebagai gantinya.
Anda tidak boleh mengekspos kunci primer database tetapi menggunakan kunci pengganti
Catatan: Kunci yang Anda buat harus (agak) dipahami manusia ( Sqlvogels Answer ).
Jika sistem Anda tidak perlu 1. hingga 4. maka tidak ada alasan untuk tidak menggunakan database PK sebagai pengidentifikasi publik Anda (beberapa jawaban). Keamanan juga tidak menjadi masalah di sini (beberapa jawaban).
sumber
Salah satu alasan saya telah menemukan, dalam waktu yang penuh saya telah melihat pengguna akhir meminta bahwa pengenal mereka berarti sesuatu (seperti memiliki awalan, atau indikator tahun itu ditetapkan). Mengubah PK itu sulit, tetapi ibu pengganti jauh lebih mudah.
Kunci utama Anda kemungkinan akan menjadi sesuatu yang Anda inginkan pengindeksan database Anda untuk alasan kinerja, dan Anda mungkin pada waktunya karena alasan teknis mengubahnya misalnya dari nomor ke panduan ... Anda tidak tahu apa alasan teknologi baru atau pengetahuan mungkin membimbing Anda. Pk Anda adalah item teknis data Anda, kunci publik adalah untuk konsumsi pengguna akhir.
sumber
InvoiceNumber
, yang memiliki arti untuk dan dapat diubah oleh pelanggan, tetapi saya juga mengeksposInvoiceID
, yang digunakan kode saya untuk secara unik mengidentifikasi faktur. Anda tidak harus (dan lebih sering tidak mau ) membiarkan kunci-pengguna menjadi kunci-penyimpanan. Pertanyaan ini tentang yang terakhir.InvoiceNumber
(untuk penyewa yang berbeda) tetapi memiliki kunci primer yang berbeda - titik (jenis ) disebutkan dalam jawaban juga.Untuk sebagian besar aplikasi, sangat penting bagi Anda untuk mengekspos kunci kepada pengguna. Untuk menggunakan sistem informasi secara efektif, pengguna sistem itu biasanya membutuhkan cara untuk mengidentifikasi informasi di dalamnya dan menghubungkan informasi itu dengan sesuatu di dunia di luar basis data. Dalam istilah basis data relasional, pengidentifikasi tersebut adalah kunci.
Salah satu pola desain yang digunakan adalah untuk membuat kunci tambahan, murni "teknis" untuk tabel database sebagai sarana abstraksi. Misalnya untuk memberikan kunci yang stabil (relatif tidak berubah) di mana beberapa kunci alternatif dapat berubah. Kunci teknis semacam itu biasanya tidak terpapar kepada pengguna akhir karena hal itu merusak abstraksi yang dimaksudkan dari persyaratan pengguna. Itu tidak ada hubungannya dengan keamanan.
Masalah / kesalahpahaman tersirat dalam pertanyaan Anda adalah karena penggunaan yang tidak tepat dari istilah kunci primer . Kunci utama hanya satu di antara beberapa kunci "kandidat" (beberapa kemungkinan pengidentifikasi dalam tabel database). Kunci utama tidak selalu memerlukan properti yang berbeda secara fundamental untuk kunci lain sehingga pernyataan dan prinsip desain yang berlaku khusus untuk kunci primer dan tidak untuk kunci lain selalu dicurigai dan sering salah.
Mengingat bahwa Anda biasanya perlu mengekspos kunci kepada pengguna Anda, apa yang seharusnya menjadi kunci itu? Cobalah untuk membuat kunci Anda Akrab, Sederhana dan Stabil. Keakraban dan kesederhanaan membuat kunci mudah dibaca dan diingat dan akan membantu menghindari kesalahan entri data. Stabilitas berarti perubahan kunci yang jarang yang juga membantu menghindari kemungkinan kesalahan identifikasi.
sumber
Ini dari komentar pada jawaban Greystone28 oleh CodeCaster. Ini adalah contoh dari apa yang Anda katakan:
Apa tujuan dalam aplikasi Anda yang memutar layanan InvoiceID?
Dengan mengekspos, saya berasumsi maksud Anda pengguna dapat melihatnya. Hanya mengeksposnya jika pengguna membutuhkannya untuk menggunakan aplikasi Anda. Ini dapat digunakan oleh dukungan teknis atau beberapa hal administratif. Saya telah bekerja dengan beberapa aplikasi yang melakukan ini. Itu membuatnya lebih mudah untuk memberikan dukungan ketika saya tahu catatan spesifik yang dimaksud.
sumber
Ini benar-benar normal karena entitas memiliki pengidentifikasi unik yang terpapar ke dunia luar. Untuk beberapa objek dimungkinkan untuk menemukan pengidentifikasi yang benar-benar memiliki makna (misalnya nomor faktur) tetapi untuk yang lain tidak ada pengidentifikasi tersebut dan oleh karena itu harus dihasilkan.
Demi konsistensi dan keterbacaan, saya menemukan ini praktik yang baik bagi semua entitas dalam sistem untuk menggunakan jenis dan nama yang sama persis untuk pengenal mereka. Biasanya pengidentifikasi ini akan diekspos (
<type> getId()
) di beberapa kelas dasar abstrak.Untuk alasan yang sama, setiap layanan dalam sistem (misalnya layanan faktur) harus menyediakan metode yang identik untuk mengakses entitas dengan pengidentifikasi mereka. Biasanya metode ini (
findById(<type> id)
) akan diwarisi dari antarmuka layanan umum atau kelas dasar.Identifier ini tidak harus menjadi kunci utama dari entitas tetapi dapat menjadi satu. Satu-satunya hal yang harus dipastikan adalah bahwa strategi generasi kunci menghasilkan pengidentifikasi unik yang cukup (tidak perlu unik secara universal tetapi setidaknya dalam sistem).
Jika sistem ini kemudian dimigrasikan (besar jika menurut pengalaman saya) ke database lain maka itu bukan masalah untuk menggunakan strategi yang berbeda (tidak didasarkan pada kunci primer) untuk membuat pengidentifikasi selama strategi tersebut kompatibel dengan yang asli.
sumber
Kunci primer ada di sana, sama seperti pegangan untuk tuple (catatan, baris) yang Anda coba akses sebagai pengembang. Ini juga digunakan dalam integritas referensial (batasan kunci asing), dan mungkin memiliki satu atau lebih kasus penggunaan juga.
Pada dasarnya, tidak ada yang buruk tentang mengeksposnya kepada pengguna, atau bahkan peretas. Karena saya tidak tahu tentang serangan yang menggunakan kunci utama misalnya.
Namun dalam keamanan, kami memiliki banyak prinsip (yang kami terima dan tidak setujui) dan kami harus mematuhinya:
Dan beberapa prinsip lainnya. Apa yang mereka katakan pada dasarnya adalah:
Jika Anda tidak perlu memaparkan data Anda, mengapa Anda melakukannya?
sumber