Bazı tablolar için bir veritabanında ikincil birincil anahtar oluşturma


22

Tablolarımın bazılarına uuid ya da rastgele bir uzun anahtar olacak olan "second_primary_key" eklemek istiyorum. Buna ihtiyacım var çünkü bazı tablolar için tamsayıları web uygulamama maruz bırakmak istemiyorum. Yani, "/ faturalar" sayfasında bir fatura listesi ve "/ faturalar /: id" bağlantısına sahibim. Burada: id bir tamsayıdır. Bir kullanıcının sistemimde kaç tane fatura olduğunu bilmesini istemiyorum, dolayısıyla "/ faturalar / 123" yerine "second_primary_key" i kullanmak istiyorum, böylece url "/ faturalar / N_8Zk241vNa" olur.

Aynısı, gerçek kimliği gizlemek istediğim diğer tablolar için de geçerli.

Merak ediyorum, bu yaygın bir uygulama mı? Bunu uygulamanın en iyi yolu nedir?

Ve nihayetinde bu tekniğin adı nedir, araştırıyorum ki?


20
Neden tamsayı tamamen kurtulmuyor?
larsbe

4
Bir tabloda istediğiniz kadar benzersiz anahtar / dizin tanımlayabilirsiniz.
abuzittin gillifirca,

2
Belki de ona ikincil bir aday anahtarı demelisin. "Birincil" sadece bir tane önerir.
Walter Mitty

4
"İkinci birincil" bir oksimorondur. Bir birincil anahtarınız var ve ikincil anahtarlarınız olabilir.
Monica'ya Zarar Vermeyi Durdurun

7
@RobbieDee bir veritabanını tamamen normalize etmemenin geçerli nedenleri var. Ve bir aday veya ikincil anahtara sahip olmak tam olarak veriyi kopyalamak değildir.
Machado,

Yanıtlar:


0

Bir UUID sütunu ekleyebilirsin, ancak gerçekten gerek yok (ve yapmamalısın). Bu bir sunum katmanıdır. 1999'da olduğu gibi 1.999 $ değerinde bir para birimi saklamak demek değildir.

Siz sadece uygulama için anında değeri gizlemenin bir yolunu istiyorsunuz. Bunu uygulamanın kendisinde veya bir veritabanı görünümü olarak yapabilirsiniz.

Sadece tek bir değerden bahsettiğimizden, belki AES veya benzeri 2 yollu şifrelemeye bakın - ne kadar hafif olursa o kadar iyi.

Hashing başka bir olasılık olabilir - karma bir yol olduğundan fatura numarasını geri almak isteyip istemediğinize bağlıdır.


48

İlişkili veritabanı modellemesinde "alternatif bir birincil anahtar" olması iyi bilinen bir kavramdır, "alternatif anahtar" veya bazen "ikincil anahtar" olarak da adlandırılır. "Potansiyel birincil anahtarlar" setine "aday anahtarlar" denir. Bkz https://beginnersbook.com/2015/04/alternate-key-in-dbms/

Bunu nasıl uygulayacağınız tamamen size bağlıdır, özellikle toplam kayıt sayısını gizlemek istiyorsanız. "En iyi yol" yoktur, izin verilen veya kullanışlı karakter kümesi, maksimum uzunluk gibi kimliğinizi büyük / küçük harf duyarlı olmasını istiyorsanız, yazdırılmış bir faturada okunabilir olmasını istiyorsanız, birilerinin Onları telefonda hatasız olarak satabiliyor olmalı, vb.


11
Ayrıca , bu senaryoyu tanımlamak için kullanılan Natural key ile Surrogate Key terimlerini de gördüm .
DanK

2
@Dari: “Bu tekniğin adı nedir” diye sordunuz - koyu harflerle. Ve eğer AES şifre çözme işlemi - belki de anında - aradığınız türden anahtarlar üretiyorsa, kullan, cevabımla çelişmez.
Doktor Brown

1
@Dari o uygulamanıza tamamen gereksiz yükü kattığından
Lamak

1
@RobbieDee Alternatif anahtarlardan hoşlanmadığınızı zaten biliyoruz, ancak bu onların işe yaramaz oldukları anlamına gelmez. Kılavuz yaklaşımını severim çünkü birçok sorunu basitleştirir.
T. Sar - Monica

1
@RobbieDee SQL Server kullanmıyoruz. MySQL kullanıyoruz. Ve çünkü biri Prod'da bir şeyler yaratacak, diyelim ki 1234 ID ile. Diyelim ki, doğal olarak, prod'de yaptığımızdan çok daha fazla varlık yaratırız. 1234, uzun zaman önce, test için bazı atılmış bir varlık tarafından alındı. Bir ürünü prod'dan test etmek zorunda kaldığımızda, onu Dev'e geri götürmeliyiz - ve birincil anahtarı zaten kullanılıyor. Göç, referanslar referans temelli ise, çok daha kolaydır. Ancak hazırda bekletme modu bir anahtarın int veya uzun olmasıyla çok daha iyi çalışır, bu yüzden bunu koruruz. Devlerim tembel ya da cahil değil - tecrübeli.
corsiKa

9

Çoğu faturanın bir fatura numarası vardır, çoğu muhasebe kuralının sıralı olması gerekir veya bir muhasebecinin yıl sonuçlarını imzalamayabilir ya da IRS (veya ülkenizdeki benzeri) sekmeleriniz üzerinde tam bir denetim yapmak isteyebilir.

Bir kullanıcı, fatura numarasından kaç müşteriye hizmet verdiğinizi veya faturalar üzerindeki numaralandırma stratejisini değiştirmeden önce ne kadar süre kaldığını tespit edebilir.

Veritabanında kaç tane fatura var, faturalarınızın toplamının bir ölçütü değildir. Yıl raporlarını Ticaret Odası'ndan istemek de dahil olmak üzere bunu öğrenmenin başka yolları da var.

Bununla birlikte, faturayı kullanıcı giriş ekranının arkasına kilitlerdim, böylece herkes talep edemez. Ardından kullanıcı girişlerinde, bekleyen faturalarını vb. İstemek için bir ajax metodolojisi kullanabilirler. Bu, verilerinizi güvence altına alır, URL'yi ajax ile gizler (hiç kimse genellikle ajax isteğinin nasıl oluşturulduğuna bakmaktan rahatsız olamaz) ve verilerin nasıl görüntülenip sunulacağını kontrol edersiniz.


7
Bankacılıkta kullanılan ortak bir strateji (çek sayıları ile), artımlı sayımı 1'de başlatmak değil, bu kesin nedenden ötürü daha büyük bir sayıdır.
DanK

Bu yüzden kimliğin eski birincil anahtarın yerine değil, ek bir birincil anahtar olması gerektiğini düşünüyorum.
Alexander,

1
Birincil anahtar demezdim. Bir sümüklü böcek, bir UUID ismi olarak giderdim, ama özünde tablodaki indekslenmiş bir alan. Her neyse kimliği, fatura numarasını söyle. Bu bir alan ama birincil anahtar değil. Birincil anahtarın benzersiz olması gerekir ve ilişkisel haritalama için dahili olarak kullanılabilir. Dizine eklenmiş alan, nerede bir sorgu ile hızlıca aranabilir. userXveryY.where ( 'INVOICE_NUMBER', 'foobarbaz10') almak (.);
Tschallacka,

1
ABD'nin özellikleri (gerekli sıralı fatura numaraları, Ticaret Odası raporları) nedeniyle gerekli olmadığına dair bir argümanla teknik bir soruyu yanıtlıyorsunuz. IMO bu soruyu iyi cevaplamıyor.
RemcoGerlich

7

Bunun için hashids kullanabilirsiniz , bu senaryoyu tam olarak çözmek için tasarlanmıştır.

Veritabanı kimliğinizi kısa bir karmaya (YouTube videosunun URL'sine benzer şekilde) kodlar ve tablonuza ikincil anahtar eklemenizi gerektirmez.


2
İsim, karma değil, tersinir fonksiyondan dolayı biraz yanıltıcıdır. Ancak bu, soruna mükemmel bir çözüm gibi görünüyor.
Çılgın Yoğurt

2
@ CrazyYoghurt True ... burada olduğu gibi isimlendirmenin nedenini açıkladılar: hashids.org/#why-hashids
Eric King

3

Başka bir benzersiz anahtar oluşturabilirsiniz, ancak yapmamalısınız. Verilen sebep için değil. Masa boyutlarını gizlemenin daha basit yolları var.

N_8Zk241vNaMasada satır başına 12 bayt, hatta indekste maliyeti saklamak . İhtiyacın olan şey için oldukça israf.

Tamsayı şifrelemek idsize alan kazandırmaz ve çalışma süresinde hiçbir şeye yaklaşmaz. Bunu nasıl yapacağınız programlama dilinize ve / veya veritabanınıza bağlıdır.

AES ile 128 bitlik bir tamsayı elde edersiniz, bu, base64'te 22 karakter, muhtemelen istediğinizden daha fazla olduğunu gösterir. DES veya 3DES gibi 64 blok büyüklüğüne sahip bir şifre, tam istediğiniz gibi 11 karakter verir.

Farklı tablolar için farklı anahtarlar kullanın.

İhtiyacınız olan tek şey, tablo boyutlarını gizlemekse, tüm tablolar için ortak bir sıra kullanabilirsiniz. Tablolarınızın çoğunda sık sık ekleme varsa, tıkanıklık olabileceğini unutmayın. Hazırda Beklet ve bir Hi-Lo algoritması gibi bir şeyle bu sorun ortadan kalkar.


Tam olarak - bu değeri sadece bir başkasını gizlemek için kaydetmek yanlıştır.
Robbie Dee,

Bu senaryoda, fatura kimliği gerçekten gizli olmadığından, ancak gizli kimlikleri veritabanındaki ilişkisel yapı olarak kullanmanın genel bir kuralı olarak, gelecekteki bir noktada verileri maskelemeniz gerektiğinde kraliyet baş ağrısına neden olacağı için çalışabilir. Onları bir özellik olarak değerlendirmek daha iyi.
DanK

burada nasıl başvuru yapabilirim?
Dari,

@Dari AES'i herhangi bir şeye nasıl uygulayabilirsiniz ? Dilinizi bilmeden kimse söyleyemez. Genellikle, AES ile çalışır , dört veya sekiz bayt olarak byte[]yazabilir, idbenzersiz bir tablo numarası ekleyebilir ve şifreleyebilirsiniz (giriş tam olarak 16 bayt olmalıdır). Seçilebilecek modlar varsa, ECB haklıdır.
maaartinus,

@DanK Ne? AES'in güvensiz olduğunu mu iddia ediyorsunuz? Anahtarı bilmeden, saldırganın saklanan bir özellikten daha iyisini yapabileceği bir şey yoktur. Hiçbir şey değil. +++ Sanırım, yorumunuzu anlamıyorum.
maaartinus

0

IMHO iki farklı birincil anahtar oluşturmak mümkün değil. Tabii ki bu uuidi bir DB'ye mevcut birincil anahtar için "takma ad" olarak koyabilirsiniz. Bu sütunun üzerine benzersiz kısıtlama içeren bir dizin koyabilirsiniz, ancak birincil anahtar (özünden itibaren) tek bir tabloda tek olandır. Bileşik birincil anahtar olabilir, ancak aradığınız şey bu değil.

Bu yüzden oraya koymanızı öneririm, ancak sadece indeks ile sahip olmak. PK ile diğer benzersiz sütunları kullanarak veri sorgulamak için işleme bileşeni oluşturabilirsiniz. "/ Fatura / ..." isteğini ele alırken sadece parametreyi kontrol edin - eğer tamsayıysa kimliği arayın, aksi halde uuid'i arayın. Ya da ID araması bir şey bulamadığında uuid aramasını bir geri dönüş olarak elde edebilirsiniz.

Ve bazı "rastgele" uuid'leri üretme hakkında: Neden "ID al, CONSTANT ekle, onaltılık yap" gibi bir şey değil. ID'nin benzersizliği, uuidin benzersizliğini sağlayacaktır, onaltılık sayı normal ölümlüler için okunması daha zordur + sabit eklemek, 00000001 gibi uuidi kullanmaktan kaçınır.


1
"Neden olmasın" gibi bir şey, kimliği al, CONSTANT ekle, onaltılığa dönüştür "- çünkü bunu çözmem oldukça kolay - bana bir URL ver ve sistemdeki diğer tüm faturalara bakacağım. IMO'da sorun yok Bunun aslında çözdüğü, sadece potansiyel olarak
yarattıkları ...

" / Faturalar / ..." için istek işlenirken sadece parametreyi kontrol edin - tamsayıysa, kimliği arayın, aksi takdirde uuid arayın "Bütün mesele (soruyu anladığım gibi) kimliğe göre arama yapan birini engellemektir ( /invoices/123, /invoices/124, ...) böylece URL’den yalnızca UUID ile arama yaparsınız.
TripeHound,

Ayrıca, tüm onaltılık sayılar harf içermez. Altta yatan tamsayılarınız ve oluşturulan altıgen sayılarınızı her zaman ayırt etmek imkansız olacaktır.
TRiG

Beklediğim gibi @CompuChip, bilgisayarlarla ilgileniyorsunuz :-) ilk görüşte onaltılık sayıyı tanıyorsunuz. Ancak, Q, başkalarının kaç tane fatura olduğunu bilmelerini sağlamak için doğrudan fatura numarasını göstermeyecek şekilde yazılmıştır. Eşime, anneme, komşuma onaltılık bir sayı gösterdiğimde ... "garip metnin" ne olduğunu bilemezler. Eğer Q içindeki fatura numaralarına göre güvenlik sorunu hakkında bir bildirim yapılacaksa, bu amaç için karmaşık bir karma yöntem önerebilirim.
Jarda

@TripeHound hala dahili olarak veya bazı kısıtlı giriş noktaları içinde ID ile arama yapabiliyor olabilir ...
Jarda

0

Her iki tuş da aynı gerçeğe işaret ediyorsa ve asla çarpışmazlarsa. Neden diğer anahtarın orijinal anahtarından özel bir hash kodu oluşturacak skalar işlevini kullanarak orijinal anahtardan türetilmediğini.

alternatif olarak, anahtarın her iki sürümünü de saklayacak bir ek haritalama tablosu oluşturabilirsiniz. bu tablo ikincil anahtarın aranması için sözlük görevi görecektir.

Anlayışıma göre, anahtarlar gizli indekslerdir ve endeksleri ne kadar fazla eklerseniz, o kadar yavaş olan kesici uçlar o kadar yavaş olur.


+1 Evet, potansiyel olarak büyük bir dizge sütunu olanı eklemek kesinlikle başkalarının önerdiği değer içermeyen işlem değildir. Depo ek yükü, dizinler eklendikçe, ekleme hızı düşmeye başlar.
Robbie Dee

0

Özel kullanım durumunuz için bir başka yaklaşım, veritabanını ve uygulamayı değiştirmek yerine, yalnızca faturalara özel bir yol oluşturabilmenizdir, böylece / faturalar /: f (id) burada f (id) id'nin bir işlevidir.

Özel rota, isteğin doğru eylem sunucusu tarafına eşlenmesinden sorumludur.


0

'Alternatif Anahtar' (AK) olarak da adlandırılan tamamen kabul edilebilir bir uygulamadır. Temel olarak AK, başka bir benzersiz endeks veya benzersiz bir kısıtlamadır.

AK'nize dayanarak yabancı anahtar kısıtlamalar bile oluşturabilirsiniz.

Muhtemel bir kullanım durumu, açıkladığınız gibi: Sürekli artan bir kimlik numarasında kümelenmiş bir PK'nız var, ancak bu numaranın görünmesini veya arama kriteri olarak kullanılmasını istemiyorsunuz, çünkü basitçe tahmin edilebilir. Bu nedenle, AK olarak rastgele benzersiz bir tanımlayıcı veya referans numaranız var ve bu, kullanıcıya sunduğunuz kimliktir.


0

Birkaç çeşit anahtar / indeks vardır. Birincil anahtar özel bir benzersiz dizindir ve cevapların dediği gibi kesinlikle başka bir benzersiz anahtar oluşturabilirsiniz. Ve çok iyi bir neden olmadıkça, veritabanınızın içindekileri göstermemek en iyisidir.

Soru faturalar ve rakamlar bağlamında olduğundan, muhasebe endüstrisinin fatura numaralarının nasıl görünmesini beklediğini araştırmak faydalı olabilir: http://smallbusiness.chron.com/assign-invoice-numbers-52422.html

Uygulamanın / müşterinin görebileceği fatura numarasıyla birlikte birincil anahtar ve başka bir benzersiz alan olan dahili bir kimliğe sahip olmak dağınık görünebilir. Ancak, müşterinin yeni bir fatura numaralandırma düzenini benimsemek istediği bir yıldan sonra, bir yıl yoldan düştüğünde net değil. Bu durumda tüm balmumu topunu yeniden numaralandırmak için iç kimliği ve diğer tablolardaki ilişkilerini bozmazsınız. Dahili kimliğinizi olduğu gibi saklar ve dahili olmayan fatura numarasını yeniden numaralandırırsınız.

İdeal olarak, tabloları / anahtarları değiştirebilecek yabancı anahtarlar üzerinde birbirine bağlamamaya çalışın ve iç tablolarınızı ve ilişkilerinizi uygulama katmanına göre şeffaf tutun.


0

Göreyim seni.

Bu, blog makalelerinin ve benzerlerinin sıklıkla sahip olduğu bir "sümüklü" alanından farklı değildir - birincil anahtardan ayrı bir veritabanı kaydına başvurmanın benzersiz bir yolu, bir URL'de kullanıma uygundur. Kimsenin bunlara karşı savaştığını hiç duymadım.

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.