Neden birincil anahtar göstermiyor


53

Eğitimimde, gerçek birincil anahtarları (yalnızca DB anahtarları değil, tüm birincil erişimciler) kullanıcıya göstermenin hatalı bir fikir olduğu söylendi.

Her zaman bunun bir güvenlik sorunu olduğunu düşünürdüm (çünkü bir saldırgan, kendine ait olmayan şeyleri okumaya çalışabilirdi).

Şimdi, kullanıcının yine de erişmesine izin verilip verilmediğini kontrol etmeliyim, bu yüzden arkasında farklı bir neden var mı?

Ayrıca, kullanıcılarımın yine de verilere erişmesi gerektiğinden, arada bir yerde dış dünya için ortak bir anahtara ihtiyacım olacak. Şimdi bu açık anahtar birincil anahtarla aynı problemlere sahip, değil mi?


Yine de bunu neden yaptığımıza dair bir örnek talep edildi, işte bir tane. Sorunun, sadece bu örnekte geçerliyse değil, prensibin kendisiyle ilgili olduğunu unutmayın. Diğer durumları ele alan cevaplar açıkça kabul edilir.

Faaliyeti yürüten Uygulama (Web, Mobil), sistemler arası iletişim için birden fazla kullanıcı arayüzüne ve en az bir otomatik API'ye sahiptir (eG muhasebe departmanı müşterinin ne yapıldığına bağlı olarak ne kadar ücretlendireceğini bilmek ister). Uygulama birden fazla müşteriye sahiptir, bu yüzden verilerinin ayrılması (mantıksal olarak, aynı DB'de depolanan veriler) sistemin sahip olması gereken bir husustur. Her talep ne olursa olsun geçerlilik için kontrol edilecektir.

Etkinlik çok ince tanelidir, bu nedenle bazı kap nesnelerinde biraradadır, “Görev” olarak adlandırır.

Üç kullanım:

  1. A kullanıcısı B görevini bazı görevlere göndermek istiyor, bu yüzden orada bazı etkinlikler yapması için ona bir link (HTTP) gönderdi.
  2. B kullanıcısı binanın dışına çıkmak zorundadır, bu yüzden Görevi mobil cihazında açar.
  3. Muhasebe, müşteriyi Görev için ücretlendirmek ister, ancak Görevi / Etkinliği, Uygulamanın REST - API'sine atıfta bulunan bir kodla otomatik olarak yükleyen üçüncü taraf bir muhasebe sistemi kullanır

Her kullanım alanı, aracının Görev ve Etkinlik için adreslenebilir bir tanımlayıcıya sahip olmasını gerektirir (veya daha kolay hale gelir).


3
ilgili: Bir vekil anahtar hiç bir kullanıcıya maruz kalmalı mı? "Değiştirilmesi gereken kullanıcılara / müşterilere açık olan herhangi bir tanımlayıcıya hazır olmanız ve bir veritabanındaki bir sıranın kimliğini değiştirmeniz ve tüm yabancı anahtarlara yapılan değişikliğin yalnızca verileri kırmasını istemesi ..."
gnat

@gnat ON UPDATE CASCADEbunun için yapıldı ( mysql'ye özgü?), sorun güvenlik olsa da, erişim kontrolü arka uçta olmalı ve yine de kullanıcıya güvenmemelidir
Izkata

2
@Izkata Evet, farklı bir veri deposunda (basit bir örnek olarak LDAP'de Kullanıcı Kimliği) başvurduğunuz veya bir yedeklemeden bazı verileri kurtarmanız gerekmedikçe. Gnat'ın orada iyi bir noktası var.
Angelo Fuchs

Pelase, "teşhir" ile ne demek istediğinizi açıklayabilir misiniz? Gerçek bir örnek yardımcı olabilir. :-)
CodeCaster 13:13

"maruz bırakma", kullanıcıya gösterme anlamına gelir. (Kullanıcı tarafından çoğunlukla bir insanı kastediyorum, ancak soru makineler için de geçerli görünüyor)
Angelo Fuchs

Yanıtlar:


38

Ayrıca, kullanıcılarımın yine de verilere erişmesi gerektiğinden, arada bir yerde dış dünya için ortak bir anahtara ihtiyacım olacak.

Kesinlikle. Hangi kaynağı istediğini başka türlü bilemeyecek olan vatansız HTTP'yi alın: sorunuzun 218306URL'sinde kimliğini gösterir. Belki aslında bir maruz tanımlayıcı olabilir mi merak ediyorsanız öngörülebilir ?

Buna olumsuz bir cevap duyduğum tek yer, gerekçesini kullandı: "Ancak URL’deki kimliği değiştirebilirler!" . Bu yüzden uygun yetkilendirme yerine GUID kullandılar.

Tanımlayıcılarınızın öngörülebilir olmasını istemediğiniz bir durumu hayal edebiliyorum: kaynak toplama. Başkalarının ilgisini çekebilecek belirli kaynakları herkese açık bir şekilde barındıran bir siteniz varsa ve bunları bir artış rakamının olduğu gibi /images/n.jpgveya yalnızca artan bir sayı /videos/n.mp4olduğu yerlerde barındırıyorsanız n, web sitenize gelen ve trafiğe bakan herkes tüm kaynaklarınızı toplayabilir.

Bu nedenle, doğrudan sorunuzu yanıtlamak için: Hayır, yalnızca programınız için anlamı olan tanımlayıcıları doğrudan "açığa vurmak" kötü değildir, genellikle programınızın başarılı bir şekilde çalışması için bile gereklidir.


2
Yönetilemeyen URL'ler (örneğin, kriptografik olarak rasgele bir 128 bit jetonu içeren) uygun yetkilendirme yöntemlerinden biridir.
KodlarInChaos 13:13

Tekrarlama saldırılarına karşı aşırı hassas olduğu gibi uygun mu? Parola sıfırlama URL'si gibi bir defalık kullanım için güzeldir, ancak statik bir kaynağı tanımlamak için bu kadar azdır, açık bir belirteç açıkken olduğu gibi, herhangi bir meşru referansı kırmadan değiştirmeden, herhangi birisinin kullanabilir o.
CodeCaster

hm? Açıkçası, SSL gerektiriyor, ancak kimliğinizi doğrulayıp onayladığınızın önemi yok. SSL üzerinden bir saldırgan belirteci öğrenemez (tıpkı çerezleri öğrenemedikleri gibi) ve tekrarlama saldırılarını engeller. Bu yaklaşımın ana dezavantajı bireysel kullanıcılar için erişimi iptal edememenizdir, bu yüzden bunu yalnızca değişmez kaynaklar için kullanmayı tercih ediyorum. Değiştirilebilir kaynaklara erişimi iptal etmek, bir saldırganın yerel bir kopyayı saklayabilmesi nedeniyle anlamsızdır.
KodlarInChaos 13:13

2
Bugünlerde aslında ne demek istediğimi ifade etmekte aciz görünmüyorum, üzgünüm. Yani, kaynağın herkese açık ancak tahmin edilemez olmasını istiyorsanız, artan bir kimliğe karşılık statik bir kaynak için rastgele bir simge kullanmak iyidir. Başka bir kullanım için, iptal etme nedeniyle bir defalık kullanımı tercih ederim.
CodeCaster

1
Yok, benim açımdan kesinlikle. O zaman "ifşa" ile ne demek istediğinizi açıklayabilir misiniz?
CodeCaster

29

Açıklamamalısınız, çünkü onu gören insanlar, DEĞİL olan 'hesap numaraları' olarak kullanmaya başlayacaklar. Örneğin, banka hesabım için hesap numaramın ne olduğunu biliyorum. Ezberledim, telefonda müşteri hizmetleri ile kullanıyorum, diğer bankalar için transfer yapmak, yasal belgeler, otomatik ödeme servisim vb. İçin form doldururken kullanıyorum. İstemiyorum değiştirmek için. Öte yandan birincil anahtar (hesabım için) bilmiyorum veya hiç görmedim.
Banka birleştirme, sistem yükseltmeleri ve değiştirmeler, vs, vs. yoluyla, başka bir sistemden yılda değişen depolayan sistem
birincil anahtarlar bu dönüşümün bazı yoluyla değişebilir, bu nedenle onun maruz kalmamış ise, yazılı veya hatırladı herhangi bir normal kullanıcı tarafından
İş anlamı olmayan anahtarlara genellikle vekil anahtarlar denir ve çoğu zaman (ancak her zaman değil) birincil anahtar olarak kullanılır.

btw, insanlar bile birincil anahtarları kötüye kullanan ve açığa çıkaran arayüzler ve programlar oluşturduklarında ve bunları tek bir şey yapmak yerine onları bu tür sistemlerin bir parçası haline getirdiklerinde, yani içsel olarak bir veritabanı kaydını benzersiz bir şekilde tanımladıklarında bile içten gerçekleşir. Aslında, bir hastanede bir veri ambarı sistemini destekleyen 6 yıllık bir süreçle yukarıdakileri öğrendim.


4
+1 ama burada tanımladığınız şey aslında bir vekil anahtar. Her tablonun bir vekil anahtarı yoktur ve vekil bunu yapsa bile "birincil" anahtar olmayabilir.
nvogel

2
+1 Hesap numarasının vekil anahtar olacağını düşünmüştüm, ancak üzerinde okudum ve% 100
haklısınız

2
+1'i kullanıcılara maruz bırakma örtük gereksinimler ekler (örneğin statik kalır)
Matt

1
Mükemmel cevap. Bunu söylememin kısa yolu, vekil anahtarların kullanışlı olması çünkü kimse onları umursamıyor ve hiç kimse onları değiştirip değiştirmemenizi umursamıyor. Onları ortaya çıkarırsanız, insanlar onlarla ilgilenmeye başlar.
JimmyJames

tl; dr: çünkü gelecek. Eğer harici bir şey bir anahtara güvenirse, uygulama daha sonra değişirse işler karışır; bu yüzden işleri kolaylaştırmak için onları az ya da çok gizli tutun.
Adam Tolley

27

Çünkü Birincil Anahtarlar bir uygulama detayıdır.

Veritabanlarını geçirirseniz, birincil anahtarlarınız ekleme sırasına, eski kayıtların kaldırılmasına bağlı olarak değişebilir ... birkaç farklı neden. Veritabanı platformlarını geçirirseniz , artık gerçek bir birincil anahtara sahip olamazsınız. PK'yi veri erişim katmanının üstünde göstermek, bütün bağlantı kaygılarını içeren sızdıran bir soyutlamadır.


3
Bir uygulama katmanı, birincil anahtar olmadan veri katmanından almak veya güncellemek istediği bir kaynağı benzersiz şekilde nasıl tanımlayacak?
CodeCaster

2
@CodeCaster - ya benzersiz indekslenmiş bir veri seti ile ya da veri erişim katmanı tarafından tedarik edilen nesnenin bir parçası olarak döndürülen ortak olmayan bir birincil anahtarla.
Telastyn

1
@CodeCaster - Geri aramanın hangi işlemin yapıldığını belirleyebilmesini sağlayan bir belirteç oluşturmanın birçok yolu vardır ve bunların tümü birincil anahtarı doğrudan geçemez.
Telastyn

2
Ancak bu, hangi katmanın hangi PK'nin hangi PKB'ye ait olduğunu (veya çevirdiğini) bilmesini gerektirir. Bana, sadece PK’yı gizleme uğruna, gereksiz bir karmaşıklık katmanı gibi geliyor. Mimarı tatmin etmenin dışında bu ne işe yarar? Amacınızla aynı fikirdeyim, sadece gerçek dünya kullanımında uygulanabilir bulmuyorum ve gerçek bir örneği takdir ediyorum.
CodeCaster

1
@CodeCaster - Hayır, orta katman aslında işini yapar ve kullanıcı arayüzünden tümüyle veri erişimi olduğunu bildirir. Dünyada pek çok kötü mimar var, ancak program tasarımının en iyi uygulamalarının çoğu bir sebepten dolayı var. Bazı uygulamalar bu sızdıran soyutlamanın riskini alabilir, bazıları ise alamaz.
Telastyn

10

Bu diğerlerinin bir kombinasyon cevabıdır (aka. Öğrendiklerimi). Bunu reddetmek istiyorsan, asıl işi yaptıklarının yanı sıra en az bir tanesini daha önce oy vermelisin. Daha fazla ilgileniyorsanız, bunun yerine diğer cevapları okuyun.

Veritabanlarının birincil anahtarını göstermemelisiniz, bunun yerine bir yedek anahtar kullanmalısınız

  1. Kullanıcılarınızın bir girişin tanımlayıcısını (en azından biraz) hatırlayabilmesini veya tanımlayabilmesini istiyorsanız. ( Graystone28s Cevap )
  2. Önceden plan yapmak ve PK'nizi büyük olasılıkla değiştirecek sistemleri (Veritabanı veya başka bir şekilde) değiştirebileceğinizi düşünebilirsiniz. ( Telastyenler Cevap )
  3. Şirketinizin sahipliğini değiştirmesine ve verilerin tamamen farklı bir sisteme taşınmasına rağmen, kullanıcılarınızın değişmeyecek verilere tutarlı bir şekilde erişmelerini sağlamak istiyorsanız. ( Michael Durrants Cevaplıyor )
  4. Eğer PK'niz tahmin edilebilir ise (bir sekans gibi) sisteminiz kaynak hasadı problemleriyle karşı karşıya kalabilir. ( CodeCasters Cevabı ) Bu, yalnızca sisteminizin hasat etmeye değer bilgileri varsa ve herhangi biri veya en azından hasat ilgisi olan herhangi biri tarafından erişilebilecek bir bilgiye sahipse geçerlidir.

Not: Oluşturduğunuz anahtar ( çeşit ) insan tarafından anlaşılabilir olmalıdır ( Sqlvogels Cevap ).

Sisteminizin 1. ila 4. arasında bir ihtiyacı yoksa, PK veritabanlarını ortak tanımlayıcı olarak kullanmamanız için hiçbir neden yoktur (cevapların birkaçı). Ayrıca güvenlik burada bir sorun değildir (cevapların bazıları).


8

Bulduğum sebeplerden biri, son kullanıcıların gördükleri zaman, tanımlayıcılarının bir anlam ifade etmelerini istediğini (önek olması veya kabul edildiği yılın bir göstergesi gibi) istemektedir. Bir PK'yi değiştirmek zordur, ancak bir vekil çok daha kolaydır.

Birincil anahtarınız, veritabanınızın performans nedenleriyle endekslemesini istediğiniz bir şey olacaktır ve teknik nedenlerden dolayı zamanında değiştirebilirsiniz; örneğin, bir sayıdan bir rehbere ... sizi aşağı yönlendirebilir. Pk'niz teknik veri öğenizdir, ortak anahtar son kullanıcıların tüketimi içindir.


7
Soru: "Birincil anahtarları açığa çıkarmak kötü mü?" . Cevabınız: "Kullanıcılar kendi tanımlayıcılarına sahip olmak isteyebilir" . Ben ilişkiyi anlamıyorum. Ben ortaya InvoiceNumberbir anlamı vardır ve müşteri tarafından değiştirilebilir olan, ama aynı zamanda maruz InvoiceIDbenim kod benzersiz fatura tanımlamak için kullandığı, hangi. Kullanıcı anahtarının depolama anahtarı olmasına izin vermek zorunda kalmazsınız (ve daha sıklıkla istemezsiniz ). Bu soru sonuncusu hakkında.
CodeCaster

Bunun güzel bir örnek olduğunu düşünüyorum çünkü APP'nizin çok kiracılı sürümüne geçerseniz, aynı sözdizimini koruyabilir ve aynı InvoiceNumber( birden fazla kiracı için) birden fazla faturaya sahip olabilirsiniz ancak farklı birincil anahtarlara sahip olabilirsiniz - bir nokta (tür ) cevabında da belirtilmiştir.
43’te

1
@CodeCaster bu soru aslında "neden aynı olmasını istemiyorsunuz" hakkında?
Angelo Fuchs

Bu durumda bakınız Telastyenler cevap veriyor .
CodeCaster

2

Çoğu uygulama için, anahtarları kullanıcılara maruz bırakmamanız çok önemlidir. Bir bilgi sistemini etkin bir şekilde kullanmak için, o sistemin kullanıcılarının normalde içindeki bilgiyi tanımlamanın ve bu bilgiyi veritabanının dışındaki dünyadaki bir şeyle ilişkilendirmenin bir yoluna ihtiyacı olacaktır. İlişkisel veritabanı terimlerinde, bu tanımlayıcılar anahtardır.

İyi kullanılan bir tasarım deseni, soyutlama aracı olarak veritabanı tabloları için ek, tamamen "teknik" bir anahtar oluşturmaktır. Örneğin, bazı alternatif anahtarların değişebileceği kararlı (nispeten değişmeyen) bir anahtar sağlamak. Bu tür teknik anahtarlar tipik olarak son kullanıcılara açık değildir, çünkü bunu yapmak kullanıcı gereksinimlerinden istenen soyutlamayı baltalamaktadır. Güvenlikle ilgisi yok.

Sorunuzdaki sorun / yanlış anlama, birincil anahtar teriminin uygun olmayan şekilde kullanılmasından kaynaklanmaktadır . Birincil anahtar, birkaç "aday" anahtardan yalnızca biridir (bir veritabanı tablosunda birkaç olası tanımlayıcı). Birincil anahtar, başka bir anahtar için temelde farklı bir özellik gerektirmek zorunda değildir; bu nedenle, özellikle birincil anahtarlar için geçerli olan ve diğer anahtarlar için geçerli olmayan iddialar ve tasarım ilkeleri her zaman şüpheli ve sık sık yanlıştır.

Genellikle bir anahtarı kullanıcınıza göstermeniz gerekeceğinden, bu anahtar ne olmalıdır? Anahtarlarınızı Tanıdık, Basit ve Kararlı kılmaya çalışın. Alışkanlık ve basitlik, tuşların okunmasını ve hatırlanmasını kolaylaştırır ve veri girişi hatalarını önlemeye yardımcı olur. Kararlılık, anahtarın nadiren değiştiği anlamına gelir; bu da yanlış tanımlama olasılığını önlemeye yardımcı olur.


1
Bu ... neye bağlı? Ne zaman uygulanacağını ve ne zaman uygulanmayacağını bilmek için bu genel konseptin arkasında yatan nedenleri öğrenmek istiyorum.
Angelo Fuchs

1
Merhaba Müşteri, lütfen bana yardım etmem için kimliğini ver. Tabii ki, onun gfds789gxb3456bgfx789fgh98076hytd6734nhg5678nghf875nhgf456. Hmm, sosyalleşmeye ne dersin? ... vekil kimlik
Michael Durrant

@Michael, Cevap güncellendi. Bu tanıdık, basit ve sağlam bir anahtar mı?
nvogel

1

Bu, Greystone28'in CodeCaster'ın cevabı üzerine yaptığı bir yorumdan. Söylediklerinize bir örnek:

Müşteri için bir anlamı olan ve değiştirilebilen InvoiceNumber öğesini açığa çıkarırım, ancak kodumun faturayı benzersiz bir şekilde tanımlamak için kullandığı InvoiceID değerini de açığa çıkarırım. Kullanıcı anahtarının depolama anahtarı olmasına izin vermek zorunda kalmazsınız (ve daha sıklıkla istemezsiniz). Bu soru sonuncusu hakkında.

Uygulamanızda Fatura Kimliği hizmetinin gösterilmesinin amacı nedir?

Açıklamak gerekirse, kullanıcının görebildiğini kastettiğinizi varsayıyorum. Yalnızca kullanıcının uygulamanızı kullanması gerekiyorsa gösterin. Teknik destek veya bazı idari işler tarafından kullanılabilir. Bunu yapan birkaç uygulamayla çalıştım. Söz konusu kaydı bildiğimde destek vermeyi kolaylaştırıyor.


Faturaların doğal tanımlayıcıları (sayıları) ancak yalnızca yazdıklarınızı gösterir. Peki ya aldıklarınız? Fatura Numaraları var, ancak çakışıyorlar (çünkü iki şirket aynı şirketi kullanıyor ve her ikisi de size bir fatura gönderiyor). Bu durumda, Fatura Kimliği'niz benzersizdir, Sayı değildir ve benzersiz kılan veriler için iyi bir tanımlayıcı olmayan Özel Ad olacaktır (çok uzun, çok sık değişiklikler, belirsiz karakterler içerebilir ...)
Angelo Fuchs

@AngeloNeuschitzer - Kullanıcı bir faturayı Müşteri adı ve numarasına göre benzersiz bir şekilde tanımlayabilirse, kullanıcının Fatura Kimliği PK'sına ihtiyacı yoktur, ancak veritabanı ve temel kodu kullanabilir. Onlar birbirini dışlayan fonksiyonlardır.
JeffO

Örneğimin 1 - 3 durumlarına bakınız. Bunların hiçbirinde Müşteri Adı, Kullanıcı için bu Nesneyi ele almanın yararlı bir yoludur (insan veya makine olsun). Fatura Kimliği PK.
Angelo Fuchs

1

Varlıkların dış dünyaya maruz kalan benzersiz bir tanımlayıcısı olması tamamen normaldir. Bazı nesneler için, gerçekten bir anlamı olan bir tanımlayıcı bulmak mümkün olabilir (örneğin fatura numarası), ancak başkaları için böyle bir tanımlayıcı yoktur ve bu nedenle oluşturulmalıdır.

Tutarlılık ve okunabilirlik adına, sistemdeki tüm varlıkların tanımlayıcıları için aynı tip ve adı kullanması iyi bir uygulama. Normalde bu tanımlayıcı <type> getId()bazı soyut temel sınıflarda ( ) gösterilecektir.

Aynı nedenden dolayı, sistemdeki her hizmet (örneğin fatura hizmeti), varlıklara tanımlayıcıları ile erişmek için aynı yöntemleri sağlamalıdır. Normalde bu yöntem ( findById(<type> id)) genel bir servis arayüzünden veya temel sınıftan miras alınır.

Bu tanımlayıcı, varlığın birincil anahtarı olmak zorunda değildir, ancak bir olabilir. Sağlanması gereken tek şey, anahtar üretim stratejisinin oldukça benzersiz tanımlayıcılar üretmesidir (evrensel olarak benzersiz değil, en azından sistem içinde gerekli değildir).

Sistem daha sonra (tecrübelerime göre büyükse) başka bir veritabanına geçirilirse, strateji orijinal ile uyumlu olduğu sürece tanımlayıcıları oluşturmak için farklı bir strateji (birincil anahtarlara dayanmayan) kullanmak sorun olmaz.


Cevabınızda nelerin cevaplanmadığını diğerlerinde açıklayabilir misiniz?
Angelo Fuchs

2
Cevabımda en azından özetin 2. ve 3. puanlarına katılmıyorum. Bunların PK'ları nesne tanımlayıcısı olarak kullanmamanın geçerli nedenleri olduğunu sanmıyorum.
Muton

0

Birincil anahtar orada, geliştirici olarak erişmeyi denediğiniz tuple (kayıt, satır) için bir tutamaç olarak. Aynı zamanda referans bütünlüğünde de (yabancı anahtar kısıtlamaları) kullanılır ve belki de bir veya daha fazla kullanım durumu vardır.

Temel olarak, onu kullanıcılara, hatta bilgisayar korsanlarına maruz bırakmanın kötü bir tarafı yoktur. Çünkü örneğin birincil anahtar kullanan bir saldırı bilmiyorum.

Fakat güvenlikte, birçok ilkemiz var (kabul ettiğimiz ve onaylamadığımız) ve bunlara uymamız gerekiyor:

  1. Kira imtiyazı ilkesi
  2. Belirsizlik yoluyla güvenlik

Ve diğer bazı ilkeler. Temel olarak söyledikleri şudur:

Verilerinizi ifşa etmeniz gerekmiyorsa, neden olmasın?


Sap kısmı kabul ettiğim yer. Güvenlik değil. Bu olabilir güvenlik geçerliyse de, kullanıcı tarafından görülebilir olmayan bağımsız bir iç anahtarı olan güvenlik konusunda gerçekten çoğunlukla değil. Buna güzel bir yan etki diyebilirim.
JensG

Neden: Soruya eklediğim örneğe bakın.
Angelo Fuchs
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.