İlişkisel bir veritabanı içinde kullanılabilir envanter / nesne / öğeler (örn. Katana) için birden çok "kullanım" (örneğin silah) nasıl modellenir


10

Bu yüzden www.ninjawars.net adresindeki öğelerin kullanımlarını genişletmeye çalışıyorum ve kullandığımız ilişkisel veritabanında bunları nasıl esnek bir şekilde temsil edeceğimi tam olarak bilmiyorum.

Yanlış ağacı havlıyor olabilirim, bu yüzden diğer yönlerde önerilerde bulunmaktan çekinmeyin, ancak şu anda her öğenin ilişkisel "etiketler" olması gerektiğini düşünüyorum.

Örneğin, bir Katana şu anda "öğeler" veritabanında bir satırdır. Bir silah ve okunabilir bir şey haline getirmek için, ben "özellikleri" bir veritabanı ve sadece aralarında bağlantı bir item_traits tablo olacağını düşünüyordum.

// Objects and their basic data

item_id | item
1 | Naginata


// Things that objects can do

trait_id | trait
1 | weapon
2 | holdable

// How those objects do those things, e.g. powerfully, weakly, while on fire

_item_id | _trait_id | item_trait_data
1 | 1 | damage: 5, damage_type: sharp, whatever, etc

Sonuçta ortaya çıkan fazladan verileri nasıl modelleyeceğimi bilmiyorum (örneğin bir kılıcın vereceği hasar, hasar türü, vb.).

Ayrıca, bir öğenin tamamının birden fazla yerde depolanmasından özellikle memnun değilim, örneğin "kısa kılıç" gibi farklı bir ada sahip bir öğenin kopyasını oluşturmak için kopyalamak zorunda kalacağım. yinelenen öğe oluşturmak için birden çok tablo.

Kaybettiğim bu şeyleri ortaya koymanın daha iyi bir yolu var mı?

Düzenleme: Ben sadece zaten sitede kullanılan bir postgresql veritabanı var, bu yüzden veri depolama için kullanmak istiyorum unutmayın.

Düzenleme: Şu anda baktığım uygulama için bir cevap ekledim.

Yanıtlar:


10

Herkese hafifçe katılmayacağım ve ilişkisel yaklaşımın burada makul olduğunu söyleyeceğim. Burada ilginç olan, öğelerin birden fazla rolü olabileceğidir. Asıl mesele, bu ilişkisel düzen ile koddaki bir OO düzeni arasındaki eşlemenin "doğal" hissetmeyeceği, ancak veritabanı tarafında birden fazla rolün (garip kodlamalar veya artıklık olmadan, sadece birleşimler olmadan) temiz bir şekilde ifade edilebileceğini düşünüyorum. .

Karar verilecek ilk şey, verilerin ne kadarının öğeye özel olduğu ve belirli bir türdeki tüm öğeler tarafından ne kadarının paylaşıldığıdır.

Tüm veriler öğeye özgü ise ne yapmalıyım :

// ITEMS table: attributes common to all items
item_id | name        | owner         | location             | sprite_id | ...
1       | Light Saber | 14 (Tchalvek) | 381 (Tchalvek house) | 5663      | ...

// WEAPONS table: attributes for items that are weapons
item_id | damage | damage_type | durability | ...
1       | 5      | sharp       | 13         | ...

// LIGHTING table: attributes for items that serve as lights
item_id | radius   | brightness | duration | ...
1       | 3 meters | 50         | 8 hours  | ...

Bu tasarımda, her öğe tüm (veya çoğu) öğenin sahip olduğu özelliklerle birlikte Öğeler tablosundadır. Bir öğenin oynayabileceği her ek rol ayrı bir tablodur.

Silah olarak kullanmak isterseniz, Silahlar tablosuna bakarsınız. Eğer oradaysa, o zaman bir silah olarak kullanılabilir. Eğer orada değilse, o zaman bir silah olarak kullanılamaz. Kaydın varlığı size silah olup olmadığını söyler. Ve eğer oradaysa, silaha özgü tüm özellikleri orada saklanır. Bu öznitelikler bazı kodlanmış formlar yerine doğrudan depolandığından, bunlarla sorgu / filtre gerçekleştirebileceksiniz. (Örneğin, oyununuzun metrikleri sayfası için oyuncuları silah hasarı türüne göre toplamak isteyebilirsiniz ve bunu bazı birleşimler ve gruplandırma hasarı_türü ile yapabilirsiniz.)

Bir öğenin birden fazla rolü olabilir ve birden fazla role özgü tabloda bulunabilir (bu örnekte hem silah hem de aydınlatma).

"Bu katlanabilir" gibi bir boolean ise, Öğeler tablosuna koyardım. Silahlar ve diğer rol tablolarında bir arama yapmak zorunda kalmamanız için orada "bu bir silah" vb. Ancak, yedeklilik ekler, bu nedenle senkronize kalmaya dikkat etmelisiniz.

Ari'nin tür başına ek tabloya sahip olması önerisi, bazı veriler öğe başına değişmezse bu yaklaşımla da kullanılabilir. Örneğin, silah hasarı her eşyaya göre değişmese de roller her eşyaya göre değişiyorsa, paylaşılan silah özelliklerini bir tabloya dahil edebilirsiniz:

// WEAPONS table: attributes for items that are weapons
item_id | durability | weapon_type
1       | 13         | light_saber

// WEAPONTYPES table: attributes for classes of weapons
weapon_type_id | damage | damage_type
light_saber    | 5      | energy

Başka bir yaklaşım, öğelerin oynadığı rollerin öğeye göre değil, yalnızca öğe türüne göre değişmesi olabilir. Bu durumda item_type öğesini Öğeler tablosuna koyarsınız ve bir ItemTypes tablosunda "bu bir silah mı" ve "katlanabilir mi" ve "hafif mi" gibi özellikleri depolayabilirsiniz. Bu örnekte, öğe adlarının her öğe için farklı olmamasını sağlarım:

// ITEMS table: attributes per item
item_id | item_type    | owner         | location
1       | light_saber  | 14 (Tchalvek) | 381 (Tchalvek house)

// ITEMTYPES table: attributes shared by all items of a type
item_type   | name        | sprite_id | is_holdable | is_weapon | is_light
light_saber | Light Saber | 5663      | true        | true      | true

// WEAPONTYPES table: attributes for item types that are also weapons
item_type   | damage | damage_type
light_saber | 5      | energy

Büyük olasılıkla eşya türleri ve silah tipleri oyun sırasında değişmez, bu nedenle bu tabloları bir kez belleğe yükleyebilir ve bu nitelikleri veritabanı birleştirmesi yerine karma tabloya bakabilirsiniz.


+1. İlişkisel veritabanı olarak ilişkisel veritabanı kullanan tek yanıt budur. Bunun ya da Nevermind'in damla önerisinin dışında ve DB'yi veri deposu olarak kullanmaktan başka her şey korkunç planlardır.

+1 Ama bu yaklaşımlar biraz esnek görünmüyor. Tutarsız göründüğüm için özür dilerim, ancak temel olarak bir kez öğeler için veritabanı yapıları oluşturmak istiyorum ... ... ve sonra öğeler için daha fazla özellik kodlayın, öğeler için veritabanına daha fazla ekler yapın, ancak değiştirmek zorunda değilsiniz gelecekte tekrar veritabanı (tabii ki nadir istisnalar hariç).
Kzqai

İlişkisel veritabanının alanlarınız hakkında bilgi sahibi olmasını ve bunların temsilini optimize etmesini istiyorsanız, bunları bir yere eklemeniz gerekir. Statik tipler gibi. Derleyicinizin alanlarınız hakkında bilgi sahibi olmasını ve bunların temsilini optimize etmesini istiyorsanız, türleri bildirmeniz gerekir. Alternatif, bazı belge veritabanları tarafından veya verilerinizi ilişkisel veritabanına bir şekilde kodlayarak kullanılan dinamik olarak yazılmış bir yaklaşımdır. Veritabanı, alanların ne olduğunu bilmiyor veya depolama alanlarını optimize edebiliyor ancak esneklik kazanacaksınız.
amitp

4

Ne yazık ki, bunun gibi durumlar ilişkisel veritabanlarının (SQL gibi) yetersiz kaldığı ve ilişkisel olmayan veritabanlarının ( MongoDB gibi ) mükemmel olduğu yerlerdir . Bununla birlikte, ilişkisel bir veritabanındaki verileri modellemek imkansız değildir ve kod tabanınızın SQL'de zaten bağımlı olduğu görülüyor, işte birlikte gideceğim model:

Bir öğe ve kullanım tablosu oluşturmak yerine, her öğe türü için bir tablo ve "[item] _type" referans tablosu oluşturun.

İşte birkaç örnek:

weapon_type_id | weapon_type
1 | sharp

weapon_id | weapon| weapon_type_id | damage
1 | Short Sword | 1 | 5

potion_type_id | potion_type
1 | HP
2 | Mana

potion_id | potion| potion_type_id | modifier
1 | Healing Elixer | 1| 5
2 | Mana Drainer | 2| -5

Bu çözüm size uzun süreli esneklik ve ölçeklenebilirlik sağlar, boşa giden alanı azaltır (ortadan kaldırmazsa) ve kendi kendini belgelendirir ("item_use_data" nın aksine). Geliştiricinin ucunda biraz daha kurulum gerektirir, ancak bence, verilerinizi saklamak için ilişkisel bir veritabanı kullanmanız gereken durumlar için mevcut en zarif çözümdür. Genel olarak, ilişkisel olmayan veritabanları, verileri modelleme konusunda daha esnek olmaları ve SQL tabanlı veritabanlarından daha performans göstermeleri ve onları "kazan-kazan" seçeneği haline getirmeleri nedeniyle oyun geliştirme için çok daha iyidir.

Düzenleme 1: potion_type_id alanında bir hata düzeltildi

Düzenleme 2: Ek perspektif sağlamak için ilişkisel olmayan ve ilişkisel veritabanları hakkında daha fazla ayrıntı eklendi


Bu sistemden çok fazla esneklik geldiğini görmüyorum. Mesela, bir cam flakon istesem, silah olarak kullanılabilseydim ve 'keskin' olabilseydim ... ... şanssız olurdu. Ayrıca, her yeni öğe türü için, aslında bunun için veritabanı yapısı oluşturmak zorunda kalacaktım. Sadece bir ya da iki tip olsa bile.
Kzqai

Ortaya koyduğunuz noktalar çok geçerlidir ve ilişkisel veritabanlarının neden bu özel duruma uygun olmadığını gösteren ek örnekleri vurgulayın. Sunduğum model, verileri, bellek korunacak ve SQL işlevselliği korunacak şekilde düzenlemenin en iyi yolunu gösteriyor. Birden çok türde olan öğeleri saklamak için, bu model altında bu verileri temsil etmenin en iyi yolu, uygun iksir ve silah özelliklerine sahip bir iksir-silah tablosu oluşturmak olacaktır. Yine, bu çözüm ideal DEĞİLDİR, ancak ilişkisel bir veritabanı kullanırken en zarif çözümdür.
Ari Patrick

@Ari: Saygısızlık yok, ama problemi tam olarak ilişkisel yaklaşımın daha az değil, daha geçerli olmasının nedeni. NoSQL (veya NoRel) veritabanlarının yüksek hacimli okumalar, dağıtılmış / yüksek oranda kullanılabilir veriler veya zayıf tanımlanmış şemalar için mükemmel olduğu bilinmektedir. Bu durum sadece klasik bir çoktan çoğa ilişkidir ve Mongo gibi dbs bunu bir RDBMS'nin yanı sıra yapmaz. Bkz. Stackoverflow.com/questions/3332093/…
alphadogg

@alphadogg Bu çoktan çoğa ilişki nasıl? Veritabanında silahlar silah türlerini biliyor, ancak silah türlerinin ilişkili oldukları silahları bilmesine gerek yok. Herhangi bir nedenle belirli bir silah türündeki tüm silahları bilmek istiyorsanız, silah belgesi koleksiyonu üzerinde yinelenen bir sorgu yazmanız yeterlidir.
Ari Patrick

@Ari: OP'nin sorusunda bir silahın birçok türü olabilir ve bir türü birçok silahla bağlantılı olabilir. Örneğin, bir iksir ve bir kılıç katlanabilir. Bir kılıç hem saklanabilir hem de silahtır.
alphadogg

3

Öncelikle, nesne yönelimli miras yaklaşımını dökün ve bileşen tabanlı bir sisteme geçin .

Bunu yaptıktan sonra, SQL düzeni aniden çok daha kolaylaşır. Paylaşılan kimlik numarasına sahip her bileşen türü için bir tablonuz var. 17 numaralı öğeyi istiyorsanız, her tabloda "17 numaralı öğe" konusuna bakın. Anahtarı olan herhangi bir tablo bileşenini ekler.

Öğe tablonuz, genel olarak öğeler için gerekli tüm verileri içerir (isim, satış fiyatı, ağırlık, boyut, tüm öğeler arasında paylaşılan herhangi bir şey.) Silah tablonuz silahlar için uygun tüm verileri içerir, İksir tablonuz tüm uygun verileri içerir iksirler için Zırh masanız zırh için tüm uygun verileri içerir. Bir zırh istiyorum, bu Eşyaya bir giriş ve Zırh'a bir giriş. İçebileceğin bir kılıçbalığı istiyorum, her masaya bir giriş yaptın ve bam, işin bitti.

Aynı kalıbın özellikle öğeye özgü olmadığını unutmayın - bunu yaratıklar, bölgeler, istediğiniz herhangi bir şey için kullanabilirsiniz. Şaşırtıcı derecede çok yönlü.


2

SQL kullanmak en büyük hatanızdı. Statik oyun tasarımı verilerini depolamak için kesinlikle UYGUN DEĞİLDİR.

SQL'den uzaklaşamazsanız, öğeleri serileştirilmiş olarak depolamayı düşünürüm. yani

item_id (int) | item (BLOB)
1             | <binary data>

Tabii ki, bu çirkin ve tüm SQL "niceties" pencereden dışarı atar, ama aslında onlara ihtiyacınız var mı? Muhtemelen, oyundaki tüm öğe verilerinizi zaten başlıyorsunuz ve asla SELECTbaşka bir şeyle okumuyorsunuz item_id.


3
(Anladığım kadarıyla) oyun çok oyunculu olduğundan ve PvP'yi desteklediğinden, çoğu oyun bilgisinin istemcide saklanma olasılığı vardır. Bu doğruysa, veriler tablodan her okunduğunda, uzaktan yararlı olmadan önce serileştirilmesi gerekecektir. Sonuç olarak, bu biçim öğeleri özelliklerine göre sorgulama ÇOK pahalı yapar; örneğin: "silah" türündeki tüm öğeleri almak istiyorsanız, her bir öğeyi geri almanız, her birinin serisini kaldırmanız, ardından basit bir sorgu çalıştırmak yerine "silah" türünü manuel olarak filtrelemeniz gerekir. .
Ari Patrick

1
Deneyimlerime göre, tüm öğeler yine de oyunun başında bellek içi önbellekte okunur. Böylece başlangıçta yalnızca bir defa serisini kaldırırsınız ve daha sonra veritabanını hiç kullanmazsınız. Bu durumda bu böyle değilse, o zaman katılıyorum, serileştirilmiş nesneleri saklamak kötü bir fikirdir.
Nevermind

Hmmm, tek şey, bu, verileri düzenlemek için beni gerekli bir arayüzle bırakıyor ki bu da rahatsız edici olacaktır.
Kzqai

2

Kaç özelliğe ihtiyacınız olduğuna bağlı olarak, farklı özelliklere karşılık gelen farklı bitlere sahip nesneler için basit bir bit maskesi kullanabilirsiniz:

000001 = holdable
000010 = weapon
000100 = breakable
001000 = throwable
010000 = solids container
100000 = liquids container

Ardından, bir nesnenin belirli bir işlev için kullanılıp kullanılamayacağını görmek için basit bit testleri yapabilirsiniz.

Yani "cam şişe" 101111 değerine sahip olabilir, yani silahlanabilir, silah olarak kullanılabilir, kolayca kırılabilir, fırlatabilir ve sıvı içerebilir.

Öğeler için oluşturduğunuz herhangi bir düzenleyicide, bir nesne üzerindeki özellikleri etkinleştirmek / devre dışı bırakmak için basit bir onay kutusu seti bulunabilir.


1
Fikri beğendim, çünkü bir öğenin kendi özelliklerini tutmasına izin veriyor ve özellikleri için veritabanında arama yapmam gerektiğini bilmiyorum, ama bu işi nasıl yapacağımı gerçekten bilmiyorum ilişkisel bağlamda. Sanırım her bit veritabanındaki özelliklerin artımlı kimlikleri ile
eşleşir

Bitmasking sabit özellikler için daha yararlı olduğunu düşünüyorum?
Kzqai

Çok fazla. Son "bit" inizi kullanırsanız ne olur? Veri katmanını artırmak ve uygulama katmanınız üzerinden bunu artırmak veya bir sütun eklemek ve aynısını yapmak için veri türünü artırmak ne kadar kolay? Ayrıca, belirli veritabanı motorunuz bit işlemleri için dizinleme için iyi ayarlanmış mı? İlişkisel bir veritabanında veri sütunlarıyla atomik kalmak en iyisidir. Tek bir sütuna birden fazla alan adını eklemeyin. Platformun avantajlarından yararlanamazsınız.
alphadogg

1
Eğer özellikler için DB bir arama tablosu istedim (muhtemelen daha sonra herhangi bir editöre dinamik olarak ekleyebilirsiniz gibi iyi bir fikir) o zaman böyle bir şey olurdu: id, bitmask, açıklama. 1,1, "tutulan"; 2,2, "Silah"; 3,4, "Kırılabilir" vb. Sabit sayı ile ilgili olarak, evet bu doğrudur. Ancak 64 bit int kullanıyorsanız, çok fazla kapsamınız olmalıdır.
Muttley

1

Projemizde , bir öğenin sahip olabileceği farklı "ekstra veriler" için item_attributes var. Bunun gibi bir şey ortaya koydu:

item_id | attribute_id    | attribute_value | order 
1        25 (attackspeed)       50             3    

Sonra şuna benzeyen bir özellikler tablosu var:

id |   name       | description
1    attackspeed    AttackSpeed:

Ari Patrick haklı olsa da, sonuçta ilişkisel db'ler bunun için yapılmadı. Dezavantajı, yeni öğeler oluşturmak için bazı oldukça karmaşık prosedürlere sahip olmamızdır (harici bir araçla yapılır - kesinlikle tavsiye ederim, Bunları manuel olarak eklemeyin, sadece kendinizi karıştırın)

Diğer seçenek , öğe şablonlarını oluşturmak için bir komut dosyası dili kullanmaktır, ardından bunları kolayca ayrıştırabilir ve yeni öğeler oluşturmak için kullanabilirsiniz. Tabii ki hala veriyi veritabanına kaydetmelisiniz, ancak bu noktada yeni öğeler yaratmanın özellikleri hakkında endişelenmenize gerek yok, hemen hemen sadece kopyalayıp eski komut dosyasını kopyalayabilir, bazı bilgileri değiştirebilir ve iyisiniz. gitmek.

Dürüst olmak gerekirse, yeni statik öğeleri nasıl oluşturduğumuzu yeniden yapacak olsaydık, muhtemelen komut dosyası öğesi şablonlarını kullanarak çok daha basit bir yaklaşıma giderdik.


1

Bu, tipik bir çoktan çoğa ilişkinizdir, herhangi bir yetenekli ilişkisel veritabanı için çok ezoterik bir şey değildir. Herhangi bir nesne için birçok özelliğiniz vardır ve herhangi bir özellik bir veya daha fazla farklı nesne türü tarafından kullanılabilir. Üç ilişkiyi (tablolar), biri ilişki ilişkisi olacak şekilde modelleyin ve işiniz bitti. Doğru indeksleme, hızlı veri okumaları yapmanızı sağlar.

Kodunuzda bir ORM katmanı oluşturun ve DB ile ara katman yazılımı arasında gidip gelen çok az sorununuz olmalıdır. Birçok ORM, sınıfları kendileri de otomatik olarak oluşturabilir ve böylece daha da "görünmez" hale gelebilir.

NoSQL veritabanlarına gelince, bunu bunlarla yapamamanız için hiçbir neden yoktur. Şu anda ticaret paçavralarında ve bloglarında bu teknoloji için amigo olmak moda, ancak kendi sorunlarının bir kısmı ile geliyorlar: nispeten olgunlaşmamış platformlar, basitçe nadiren değiştirilmiş okumalar için harika (bir profildeki bire çok twit gibi) ama karmaşık dinamik okumalar veya güncellemeler, zayıf destekleyici araç zinciri, yedekli veriler ve beraberindeki bütünlük sorunları vb. için fakirdir. Ancak, değişen derecelerde işlem yeteneklerinden ve ek yüklerinden ve daha kolay dağıtım / çoğaltma modellerinden kaçındıklarından daha iyi ölçeklenebilirlik cazibesi sunarlar. .

İlişkisel veritabanlarının NoSQL veritabanlarına karşı olağan hobgoblin performansıdır. Farklı RDMBS'lerin farklı derecelerde ek yükü vardır, bu da onları Facebook veya Twitter düzeylerine ölçeklendirme için daha az tercih edilir hale getirir. Ancak, bu sorunlarla karşılaşmanız pek olası değildir. O zaman bile, basit SSD tabanlı sunucu sistemleri performans tartışmasını işe yaramaz hale getirebilir.

Açık olalım: Çoğu NoSQL veritabanı temel olarak karma tablolar dağıtır ve kodunuzdaki karma tabloyla aynı şekilde sizi sınırlar. tüm veriler bu modele tam uymaz. İlişkisel Model, veriler arasındaki ilişkileri modellemek için çok daha güçlüdür. (Karıştırıcı faktör, çoğu RDBMS'nin web'in popüler% 0.0001'inin, yani Facebook ve diğerlerinin talepleri için zayıf ayarlanmış eski sistemler olmasıdır.)


Onlara toplu olarak başvuracaksanız, veritabanları hakkında konuşmaya bile zahmet etmeyin. NoSQL anlamlı olarak tartışılabilecek bir varlık değildir, SQL fanbois'in bu tanımlanmış grubun bir veritabanının bir özellikten yoksun olması durumunda hepsinin bu özellikten yoksun olduğu kusurlu mantığı uygulamak için kullanışsız bir kitle referansıdır.
aaaaaaaaaaaa

NoSQL, NoSQL iticilerinin uyum sağlamayı seçtiği bir terimdir. Nedenini bilmiyorum, çok açıklayıcı değil. Ama bu bir tür aşağılayıcı değil. Birkaçıyla çalıştıktan sonra, alfadogg'un bunları tanımlaması adil.

Belki benim yorumum biraz sertti, yine de, bu isimden ve gruplamadan nefret ediyorum, insanlar bu basitleştirilmiş dünya görüşünü koruduğunda farklı veritabanı sistemlerinin daha ince ayrıntıları hakkında nitelikli bir tartışma yapmak imkansız.
aaaaaaaaaaaa

@ eBusiness: RDBMS karşıtı kamp olduğu göz önüne alındığında yorumunuzu eğlenceli buluyorum, eğer varsa kendi gruplarını "NoSQL" olarak kendi kendine görevlendirdi. Kuşkusuz, birçoğu bu ismin arkada reddedildiğini görmek istiyor. Özellikle birçoğu nihayet fiziksel uygulamalarına SQL katıyor. Onlar hakkında konuşmak için, yorumunuzu sert olarak almadım ya da kalın bir cildim var, seçiminiz! :) Yani, çay partisi hakkında konuşabiliriz, neden NoSQL veritabanı grubu olmasın?
alphadogg

Bu adil, ilişkinin tamamen çoktan çoğa olduğunu biliyorum. Beni gerçekten normalleştirilmiş tarzda yaratmamızı engelleyen şey, bir öğeyi oluşturacak "şeylerin" en az iki tabloya yayılacağı düşüncesidir. Bence atomik uçlar yaratamama fikrinden hoşlanmıyorum.
Kzqai

0

Burası, Entity Framework 4 ve (CTP) kod ilk özelliği gibi daha kullanışlı OR haritacılarının gerçekten yararlı olduğunu bulduğum yer . Sadece sınıfları ve ilişkilerini normal kodda yazıyorsunuz ve bunları dekore etmek veya herhangi bir aracı manuel olarak çalıştırmak zorunda kalmadan EF, gerekli bağlantı tabloları ve tümüyle SQL mağazasında destek deposunu oluşturacak ... gerçekten yaratıcılık imo'yu serbest bırakıyor ^^


Ben, kod ve sınıflar ve sadece kod ilk önce yaratacağım ... ... sadece sonra varolan veritabanı yapısına çevirmek lazım.
Kzqai

0

İşte şimdi düşündüğüm şey:

Her "özellik" aslında zaten kod değişiklikleri gerektirir, bu yüzden sadece özellikleri (ve onlar için herhangi bir varsayılan veri) kodun kendisi (en azından şimdilik) tutmaya karar verdim.

Örneğin $traits = array('holdable'=>1, 'weapon'=>1, 'sword'=>array('min_dam'=>1, 'max_dam'=>500));

Ardından öğeler veritabanında json_encode()JSON biçiminde depolanmak için işlevi kullanacak bir "trait_data" alanı alır .

item_id | item_name | item_identity | traits
1 | Katana | katana | "{"holdable":1,"weapon":1,"sword":{"min_dam":1,"max_dam":1234,"0":{"damage_type":"fire","min_dam":5,"max_dam":50,"type":"thrown","bob":{},"ids":[1,2,3,4,5,6,7]}}}"

Plan, öğelerin tüm varsayılan istatistikleri üst özelliklerinden devralacak ve yalnızca özelliklerin varsayılan olarak ayarlandığından farklılıkları belirten fazla sürüş özelliklerine sahip olacağıdır.

Özellikler alanının dezavantajı, ben json kısmını elle düzenlerken ... ... veritabanında bulunan verilerle bunu yapmak gerçekten kolay veya güvenli olmayacak.


1
Yeni bir özellik eklediğinizde ne olur? Bu ne sıklıkla olabilir? Kod bakım iş yükünüz üzerindeki aşağı yönde etkiler ne olur? Nesne örneklerinizin bu verileri tutmak için dinamik olarak oluşturulduğu (ORM seçiminiz yoluyla) çoktan çoğa olarak saklamanın aksine.
alphadogg

Teşekkürler, bu iyi bir nokta, yeni özellikler eklemek önemsiz olmayacak. Analiz felçime ekledin. : p
Kzqai

Üzgünüm, ama bu oldukça kritik. Sadece düşünmen gerek. Oyun geliştirmenizin çalışabilmesi için yeni bir özellik eklemek için bazı silahların güncellenmesi gerektiğinde ne yapmanız gerektiğini aklınızdan geçirin.
alphadogg

-1

Bu biraz hacky, ve ben iyi DB tasarımı garanti etmez; DB derslerim bir süre önceydi ve akla hemen gelmiyorlar. Ancak, öğelerin, örneğin 10'dan az öğeye sahip olduğu garanti edilirse, her öğeye bir attribute1 alanı ve attrib22 alanı verebilir ve attribute10'a kadar devam edebilirsiniz. Özellik sayısını sınırlama pahasına çoktan çoğa öğe özelliği tablosuna olan ihtiyacınızı ortadan kaldıracaktır.

Geriye dönüp baktığımda, bunun korkunç bir tasarım olduğundan eminim, ancak rahat bir ilişkisel veritabanı ile yapışabileceğiniz ve haritalanmamış bölgeye girmeniz gerekmediği anlamına geliyor. Ödemenin değip değmeyeceğine karar vermek size kalmış.


Bu korkunç bir tasarım, asla yapma. Bir veritabanı kullanmamanız daha iyi olur.
ZorbaTHut

-1

Nevermind iyi bir cevap verdi, ama merak ediyorum, bunun için bir veritabanına bile ihtiyacınız var mı? Tüm verileri düz bir dosyada saklamak ve açılışta programa yüklemek bunu yapmanın en akıllı yolu gibi görünüyor.

Düzenleme:
Doğru, vatansız istek odaklı bir ortamda daha iyi veriyi bir veritabanında tutmak. Verilerinizi bir dosyaya yazın ve Nevermind tarafından önerilen türde bir veritabanına dönüştürmek için bir kod parçası yazın.

Alternatif olarak, nesnelerin sayısı çok fazla değilse, bir kod dosyasında lotu tam olarak bildirmek en hızlı yöntem olabilir.


Hata, zaten kullanımda olan bir sitem var ve sitenin geri kalanıyla entegre oldum.
Kzqai
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.