Kilit sorun: anahtar strateji benim veritabanında kullanmak gerekir?

6 Cevap php

Sorun: Benim veritabanında otomatik artan birincil anahtarı kullandığınızda, bu her zaman olur:

Ben 10 Öğeler ile Sipariş saklamak istiyorum. Sipariş Öğeler Sipariş aittir. Yani, sipariş saklamak (doğru?, Eşzamanlılık söz konusu olduğunda tehlikeli) son eklenen id için veritabanı isteyin ve sonra yabancı anahtar (order_id) ile 10 Öğeler saklayın.

Yani her zaman yapmak zorunda:

INSERT ...

last_inserted_id = db.lastInsertId ();

INSERT ... INSERT ... INSERT ...

ve bu ben bir yabancı anahtar gereken hemen hemen tüm vakalarda INSERT işlemleri kullanarak engelleyen inanıyorum.

Onlar gerçekten iyi iseniz Yani ... burada bazı çözümler, ve ben bilmiyorum:

A) Don't use auto_increment keys! Use a key table? Key Table would have two fields: table_name, next_key. Every time I need a key for a table to insert a new dataset, first I ask for the next_key by accessing a special static KeyGenerator class method. This does a SELECT and an UPDATE, if possible in one transaction (would that work?). Of course I would request that for every affected table. Next, I can INSERT my entire object graph in one transaction without playing ping-pong with the database, before I know the keys already in advance.

B) Using GUUID / UUID algorithm for keys? These suppose to be really unique worldwide, and they're LARGE. I mean ... L_A_R_G_E. So a big amount of memory would go into these gigantic keys. Indexing will be hard, right? And data retrieval will be a pain for the database - at least I guess - integer keys are much faster to handle. On the other hand, these also provide some security: Visitors can't iterate anymore over all orders or all users or all pictures by just incrementing the id parameter.

C) Stick with auto_incremented keys? Ok, if then, what about transactions like described in the example above? How can I solve that? Maybe by inserting a Ghost Row first and then doing an transaction with one UPDATE + n INSERTs?

D) What else?

6 Cevap

Emir saklarken, need işlemler sadece yarısı ürünleri veritabanına eklenen durumları önlemek için.

Veri tabanı ve konnektörü bağlı olarak, son-insert-id işlevi tarafından döndürülen değeri işlem bağımsız olabilir. Örneğin, MySQL, mysql_insert_id (eşzamanlı yapıyorsun ne diğer müşteriler tarafından etkilenen olmadan) o belirli istemci son sorgu için tanıtıcısı döndürür.

Hangi veritabanı kullanıyorsunuz?

Evet, genellikle masa sorgusu naif bir select max (id) kullanıyorsanız, özellikle, bir kayıt ekleme ve daha sonra otomatik oluşturulan anahtar kötü bulmak için tekrar seçmek için çalışıyor. Kısa sürede iki iş parçacığı kayıtları max (id) yaratıyor gibi aslında mevcut parçacığı kullanılan son id iade olmayabilir çünkü bu.

Bunu önlemek için bir yolu veritabanında bir dizi oluşturmaktır. Sizin kodunuz sequence.NextValue sonra sonra ekler yürütmek için (veya tek seferde bu seçimi ve ekler yapan bir daha karmaşık bir SQL deyimi zanaat olabilir) bu değeri kullanın seçin. Diziler atomik / thread-safe.

MySQL sana hep doğru cevap vereceğine inanıyorum yürütme sonuçları son eklenen id için sorabilirsiniz.

SQL Server destekler SCOPE_IDENTITY (Transact-SQL) hangi işlem sorunu ve eşzamanlılık sorunu dikkat çekmek gerekir.

I auto_increment ile sopa söyleyebilirim.

(MySQL kullanıyorsanız varsayarak)

"(Sağ, bu eşzamanlılık söz konusu olduğunda tehlikeli olan?) Son eklenen id için veritabanı isteyin"

Eğer last_insert_id MySQLs () işlevini kullandığınızda, yalnızca oturumda ne oldu bakın. Yani bu güvenlidir. Sen ths söz:

db.last_insert_id()

Ben ne olduğunu çerçeve veya dil bilmiyorum, ama ben bu kapakların altında MySQL'in last_insert_id () kullanır zannedebilir (değilse, bu oldukça işe yaramaz veritabanı soyutlama fromework olduğunu)

"Ben bu w neredeyse tüm INSERT durumlarda işlemleri kullanarak engelleyen inanıyorum"

Ben neden görmüyorum. Lütfen açıklayınız.

D) Sequence

: DBMS mevcut olmayabilir, ama eğer, zarif sorunu çözer.

Postgresql için Sequence Functions bakabilirsiniz

Bu soruya kesin ve genel bir cevap yoktur.

Yeni kayıt eklediğinizde auto incrementing columns kullanımı kolaydır. Aynı işlem içinde yabancı anahtar olarak kullanmak için, bu kadar yalındır değildir. Sen yeni oluşturulan anahtarı almak için veritabanı belirli komutları gerekir. Bu teknoloji örnek için SQL Server, bazı veritabanları için yaygındır.

Sequences Eğer bir satır eklemek önce anahtarı almak gerekir, ama sonunda en kolay yabancı anahtar olarak kullanmak için, çünkü kullanmak zor gibi görünüyor. Bu teknoloji, örneğin oracle için belirli bir veri tabanları için yaygındır.

Eğer Hibernate or NHibernate kullandığınızda, bazı optimizasyonlar artık mümkün değil, çünkü tuşlarını artan otomobil kullanımı önerilmez. Ek bir tablo kullanan bir hi-lo algoritması kullanılması tavsiye edilir.

Arasında veri paylaşımı yaparken Guids, örneğin, güçlü veritabanları, sistemleri, bağlantısız senaryolar, ithalat / ihracat vb birçok farklı veritabanlarında, tabloların çoğu sadece birkaç yüz kayıt içerir, bu nedenle bellek ve performans değil böyle bir sorun. NHibernate kullanırken tuşlar sıralı olduğunda bazı veritabanları daha iyi gerçekleştirmek, çünkü, sıralı GUID'lerine üreten bir guid jeneratör olsun.