mgsmus mustafa abi bu açıklamalarından sonra oturdum kendi kendime birşeyler çıkarmaya başladım hem burda ki arkadaşlara örnek olması açısından hemde eksik kaldığım içinden çıkamadım bir kaç şey var. Kodlarımı inceleyip eksik hatalı yanlış yaptığım yerleri söyleyebilir misin https://github.com/metapodcod/laraveldynamicproductvariants
Ürün ve Ürün detay tablolarının oluşumu
- Düzenlendi
@mgsmus hocam, şimdi mysql'de yaptığımız sorgularda grup olarak nasıl arayabiliriz. Yaptığım sisteme göre SKU numarasını ilişkileri tutan tablodan alıyorum, bunu bir türlü çözemedim.
Örneğin verilerimiz:
gelen_veri
veri array veya herhangi bir şekilde post olarak da gelebilir. Ancak nitelik_Id = 1 tanim_Id = 2 ve nitelik_Id = 6 tanim_Id = 7.
Mysql sorgu sonucu ile yukarıda ki kriterlere tam olarak uyan SKU alacağım. Aşağıda ki tabloya göre 1 numaralı ürüne ait SKU1 dönmeli.
urun_sema
Id - urun_grup - nitelik_Id - tanim_Id - urun_Id - SKU
1 - urun_grup - 1 - 2 - 1 - SKU1
2 - urun_grup - 6 - 7 - 1 - SKU1
3 - urun_grup - 1 - 2 - 1 - SKU2
4 - urun_grup - 6 - 8 - 1 - SKU2
5 - urun_grup - 1 - 2 - 1 - SKU3
6 - urun_grup - 6 - 9 - 1 - SKU3
7 - urun_grup - 1 - 3 - 2 - SKU4
8 - urun_grup - 6 - 7 - 2 - SKU4
9 - urun_grup - 1 - 3 - 3 - SKU5
10 - urun_grup - 6 - 4 - 3 - SKU5
mgsmus Merhaba Hocam,
2 Gündür Buradaki Yazıları ve Diğer https://laravel.gen.tr/d/2771-e-ticaret-sistemi/7 Adresindeki Yazılarını Okuyorum ve Ürünler Varyasyon Olayını Çözmeye Çalışıyorum.
Urunler
+---+------------+---------------+
| ID | StokKodu | UrunAdi
+---+------------+---------------+
| 1 | DP01 | Elbise |
+---+------------+---------------+
UrunVaryasyonlar
+---+---------+------------------+
| ID | UrunID | VaryasyonAdi
+---+---------+------------------+
| 1 | 1 | Beden |
| 2 | 1 | Renk |
+---+---------+------------------+
UrunVaryasyonSecenekleri
+---+---------+-----------------+----------------+-------------+
| ID | UrunID | VaryasyonID | SecenekAdi | SkuKodu
+---+---------+-----------------+----------------+-------------+
| 1 | 1 | 1 | Small | S |
| 2 | 1 | 1 | Medium | M |
| 3 | 1 | 1 | Large | L |
| 4 | 1 | 2 | Beyaz | B |
| 5 | 1 | 2 | Siyah | S |
| 6 | 1 | 2 | Mavi | M |
+---+---------+-----------------+----------------+-------------+
UrunSKU
+---+---------+------+---------------------------+------+---------------+--------------+
| ID | UrunID | Sku | VaryasyonSecenekID| Fiyat | StokMiktari | AktifPasif
+---+---------+------+---------------------------+------+---------------+--------------+
| 1 | 1 | DP01-S-B | 1,4 | 10,00 | 5 | 1 |
| 2 | 1 | DP01-M-B | 2,4 |15,00 | 10 | 1 |
| 3 | 1 | DP01-L-B | 3,4 | 20,00 | 15 | 1 |
| 4 | 1 | DP01-S-S | 1,5 | 25,00 | 20 | 1 |
| 5 | 1 | DP01-M-S | 2,5 | 30,00 | 25 | 1 |
| 6 | 1 | DP01-L-S | 3,5 | 35,00 | 30 | 1 |
| 7 | 1 | DP01-S-M | 1,6 | 40,00 | 50 | 0 |
| 8 | 1 | DP01-M-M | 2,6 | 45,00 | 50 | 0 |
| 9 | 1 | DP01-L-M | 3,6 | 50,00 | 50 | 0 |
+---+---------+------+---------------------------+------+---------------+--------------+
Bu Şekilde Tablo Oluşturdum. "UrunSKU" Adlı Tablomun Olup Olmadığı Hakkında ve Kullanıcı İlgili Varyasyonları Seçerken Bu Tablo İle Stok Kontrolü ve Fiyat Kontrolünü Yapabilir miyim Bilemedim.
VaryasyonSecenekID Ne İçin Yaptınız Diye Soracak Olursanız;
Kullanıcı Varyasyon Secimi Yaptığında Karsısına O Varyasyonla Birlikte Secilecek Olan 2. Varyasyon Varsa 3.Varyasyon Hatda Varsa 4.Varyasyonları Listelemek İçin Karşılastırma İşlemini Yapabilmek İçin Oluşturdum.
Tabi Bu İşlemleri Yapıp Yapamayacağım Konusunda Kafamda Oturmuş Net Bir Durum Yok.
Bu Konu Hakkında Yardımcı Olabilir misiniz ?
- Düzenlendi
kadirakkus9 Tablo isimlendirmeleriniz çok karışık ve bazı yerler farklı olmuş. Aslında farklı bir cevap yazacaktım ama sildim. Ben size temel tabloları yazayım:
categories
Ürün kategorileri.
+----+-----------+-----+-----+-----------+
| id | parent_id | lft | rgt | name |
+----+-----------+-----+-----+-----------+
| 1 | | 1 | 6 | Erkek |
| 2 | 1 | 2 | 5 | Giyim |
| 3 | 2 | 3 | 4 | Üst Giyim |
+----+-----------+-----+-----+-----------+
Burada Nested Set veri yapısı kullanılıyor, forumda aratabilirsiniz. Örneğin bu tabloya göre Erkek kategorisinin içinde hangi kategoriler var derseniz (ve Erkek kategorisini de sonuca dahil ederseniz)
SELECT *
FROM categories
WHERE lft >= 1
AND rgt <= 6
ORDER BY lft
şeklinde sorgu atılır. Bu sorgu size şunu döner:
1 Erkek
2 Giyim
3 Üst Giyim
ve mesela şunu yapmanıza olanak tanır:
Erkek > Giyim > Üst Giyim
Bu yapıyı Laravel'de kolayca kullanmak için şu paketi kullanıyorum:
https://github.com/lazychaser/laravel-nestedset
Yapıyı resimle anlatmak gerekirse (lft ve rgt nedir mesela):
products
Ana ürünler
+----+---------+
| id | name |
+----+---------+
| 1 | T-Shirt |
+----+---------+
product_categories (pivot)
Hangi ürün hangi kategoride
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 3 |
+------------+-------------+
attributes
Ürün özellikleri
+----+-------+
| id | name |
+----+-------+
| 1 | Beden |
| 2 | Renk |
+----+-------+
attribute_values
Özellik değerleri
+----+--------------+---------+------+
| id | attribute_id | name | code |
+----+--------------+---------+------+
| 1 | 1 | S | S |
| 2 | 1 | M | M |
| 3 | 2 | Kırmızı | KRM |
| 4 | 2 | Mavi | MVI |
+----+--------------+---------+------+
product_attributes (pivot)
Hangi ürün hangi özelliğin hangi değerine sahip. Bu tabloya göre T-shirt, S beden ve kırmızı renge sahip
+------------+--------------+----------+
| product_id | attribute_id | value_id |
+------------+--------------+----------+
| 1 | 1 | 1 |
| 1 | 2 | 3 |
+------------+--------------+----------+
variants
Ürünler/Varyantlar/Varyasyonlar...
+----+------------+-------------+-------------------------+
| id | product_id | sku | name |
+----+------------+-------------+-------------------------+
| 1 | 1 | 1-S-KRM | Kırmızı S Beden T-Shirt |
+----+------------+-------------+-------------------------+
shops
Dükkanlar/Şubeler. Neden böyle bir tablo var derseniz sebebi product_stock tablosunda yazıyor:
+----+-----------------+
| id | name |
+----+-----------------+
| 1 | Kadıköy Şube |
| 2 | Beylikdüzü Şube |
+----+-----------------+
product_stock (pivot)
Ürün stokları tablosu. Birden fazla şube vs olabileceği için her ürün her mağazada farklı stokta ve nadiren de olsa farklı fiyatta yer alabilir. O yüzden ayrı tabloda tutulması mantıklı (Tabloya göre Beylikdüzü mağazasında Kırmızı S beden t-shirt stokta kalmamış)
+---------+------------+------------+----------+-------+
| shop_id | product_id | variant_id | quantity | price |
+---------+------------+------------+----------+-------+
| 1 | 1 | 1 | 17 | 29.95 |
| 2 | 1 | 1 | 0 | 29.95 |
+---------+------------+------------+----------+-------+
Senaryo:
- Kullanıcı ürün detay sayfasına geldi. product_id=1 yani hangi ürün olduğunu biliyoruz.
- Hangi ürün olduğunu bildiğimiz için product_attributes tablosundan product_id=1 olan özellikleri alıp ekrana gösterdik. Detay sayfasında şimdi sırasıyla Beden ve Renk gösteriyoruz.
- Bu beden ve renk altında attribute_values tablosunda yer alan değerleri gösteriyoruz ama bunu yaparken sadece product_attributes içinde yer alan value_id'lerine göre listeletiyoruz. Yani beden altında S; renk altında ise sadece Kırmızı listelendi.
- Kullanıcı S seçti, Kırmızı seçti. S'nin kodu S, Kırmızının kodu KRM, product_id ise 1. Şu an aslında SKU kodunu tekrar oluşturmam için tüm veri var. Hepsini - ile, sırasını bozmadan birleştirince 1-S-KRM elde ettim.
- Elde ettiğim bu 1-S-KRM kodu ile variants tablosuna where sku = '1-S-KRM' şeklinde sorgu atarak seçilen özelliklere denk gelen varyantı buldum.
- Sepete ekledim.
Bu varyant elde etmenin başka yolları da var. Herkes kendi sistemine, tablo yapısına göre kodluyor. Sizin VaryasyonSecenekID olayı mantıklı, kullanabilirsiniz. Örneğin şöyle bir pivot tablo da tutulabilir:
variant_attribute_values
+------------+----------+
| variant_id | value_id |
+------------+----------+
| 1 | 1 |
| 1 | 3 |
+------------+----------+
ya da product_attributes tablosuna variant_id eklenebilir.
SKU kodu otomatik oluşan bir kod olmalı ve tersten tekrar oluşturulabilmeli. Bu kod müşterinin gireceği bir kod değil. Varsa öyle bir kod, barkod gibi, onu ayrı bir alanda tutmalısınız.
- Düzenlendi
Hocam Cevabınız İçin Teşekkür Ederim. Tablo İsimlendirmelerini Genellikle Türkçe Kullandığım İçin Biraz Karışık Oluyor. Bu Sefer Sanırım Olayı Çözdüm. Birazdan Uygulamaya Geçeceğim. Yalnız Aklıma Bir şey Takıldı.
Bu Durumda Kullanıcı S Bedenini Seçtikten Sonra S Bedenine Ait Kırmızı Renkteki Ürünün Stokta Olup Olmadığını Nasıl Gösterebiliriz.
Ayrıca,
Anlattığınız Sistemde İlerde Karşımıza Çıkabilecek Herhangi Bir Sorun Var mı ?
- Düzenlendi
kadirakkus9 Stoğu sizin yaptığınız gibi varyant tablosunda tutuyorsanız varyanta ulaştınız mı zaten stocğa da ulaşmış oluyorsunuz. Benim dediğim gibi product_stock kullanırsanız shop_id ve variant_id ile o tabloya sorgu atacaksınız.
kadirakkus9 Anlattığınız Sistemde İlerde Karşımıza Çıkabilecek Herhangi Bir Sorun Var mı ?
Kesinlikle Öyle Bir Şey Söz Konusu Olamaz, Garantisi Bizzat Şahsım. Bunu 4 Kişiye Daha Anlattım, Biri Hepsiburada’yı, Diğeri Trendyol’u, Bir Diğeri De Gittigidiyor’u Kurdu. 4. Kişi Bu Bana Pek Uymadı Dedi, O Da Nevzat Tabi ki sorun vardır, siz ilerledikçe karşınıza çıkar, ben sadece kitabın önsözünü yazdım size.
Verdiğiniz Bilgiler İçin Teşekkür Ederim Hocam.
- Düzenlendi
Merhaba @mgsmus discount_price alanını product_stock tablosuna mı eklemek mantıklı yoksa product_discounts adında tablo açmak mı daha efektif bir kullanım olur.2. sorumda kategoride lft ve rgt migration ile biz ekliyoruz dime(nested ile bir alakası yok) lft ve rgt create ederken nasıl bir mantık ile değerlerini veriyoruz.
3.sorum ürün url slug ile aratacağım . ürünün slug vartiantta mı tutulmalı
- Düzenlendi
echo75 İlk sorunuza cevap veremiyorum, 9 ay önce konuşulmuş bir konu, konuyu incelemem lazım.
İkinci sorunuzun cevabı ise, ilk kategorinin left değeri 1, right değeri 2 oluyor. Aynı seviyede bir kategori ekleyeceğiniz zaman yeni kategorinin değerleri bir öncekinin left+1, right+1 oluyor. Eğer ilk kategorinin altına bir kategori ekleyecekseniz oradaki değerleri bulup +2 ekleyerek yer açıyorsunuz ve araya ekliyorsunuz. Şöyle mesela:
SELECT @newrgt := rgt,
@newparentid := 1
FROM categories
WHERE id = 1;
UPDATE categories
SET rgt = rgt + 2
WHERE rgt > @newrgt;
UPDATE categories
SET lft = lft + 2
WHERE lft > @newrgt;
INSERT INTO categories
(name, parent_id, lft, rgt)
VALUES ('Alt kategori', @newparentid, @newrgt + 1, @newrgt + 2);
Kısa yolu olan bir şey değil yani. Her seferinde değerlerin baştan hesaplanması gerekiyor. Ekleme, silme ve taşıma işlemleri için.
Üçüncü sorunuzun cevabı evet, slug varyantta tutulacak çünkü sattığınız ürün o. Ana ürünün görevi sadece gruplama gibi işlemler.
- Düzenlendi
mgsmus Öncelikle geri dönüşünüz için çok teşekkür ederim.
+----+-----------+-----+-----+-----------+
| id | parent_id | lft | rgt | name |
+----+-----------+-----+-----+-----------+
| 1 | null | 1 | 6 | Erkek |
| 2 | 1 | 2 | 5 | Giyim |
| 3 | 2 | 3 | 4 | Üst Giyim |
| 4 | null | 1 | 6 | Elektronik|
| 5 | 4 | 2 | 5 | Bilgisayar|
| 6 | 5 | 3 | 4 | Laptop |
+----+-----------+-----+-----+-----------+
Erkek ve Elektronik eklendim. Eleltronik için lft değerleri 1,2,3 mü olmalı yoksa. Erkek,Giyim,Üst Giyim lft degeleri 1,2,3 üzerinden devam edip 4,5,6 mi olmalı orayı tam anlayamadım
Product_discount içinde variants tablosuna discount_id ekledim. product_discounts diye bir tablo açtım bu konuda da müsait olduğunuzda geri dönüşünüzü bekliyorum. Teşekkü ederim
+----+-----------+-----+-----+------------+
| id | parent_id | lft | rgt | name |
+----+-----------+-----+-----+------------+
| 1 | null | 1 | 6 | Erkek |
| 2 | 1 | 2 | 5 | Giyim |
| 3 | 2 | 3 | 4 | Üst Giyim |
| 4 | null | 7 | 12 | Elektronik |
| 5 | 4 | 8 | 11 | Bilgisayar |
| 6 | 5 | 9 | 10 | Laptop |
+----+-----------+-----+-----+------------+
Ürün indirimleri dediğiniz kampanyalar ise discount_id eklemeyin, ayrı bir pivot tabloda variant_id, discount_id tutun. Böylece ürüne birden fazla kampanya uygulanabilir.
- Düzenlendi
Ürün varyasyonuna göre resim tablosu nasıl olmalı
varyant images adında tablo oluşturup variyants id ile mi ilişkilendirmeli Yani
id--------images_name-------------varyants_id
1--------beyaz-t-shirt-1-.jpeg--------1
2--------beyaz-t-shirt-2-.jpeg--------1
3--------sari-t-shirt-1-.jpeg--------2
4--------sari-t-shirt-2-.jpeg--------2
Resimler varyant tablosunda da tutulabilir ama bir ürünün renk dışında da varyasyonları olabileceği için null alanlar çok olabilir.
Değişik renkte ki ürüne ait her renk için örnek 3 resim olsa
2 renk x 3 = 6 resim.
Ama beden vb. attribute değerlerinde resim olmayabilir.
Sizce doğrumu tablo yapım.
mgsmus variant mantığını bu şekilde 4,5 tabloda veri tutarak yapmak yerine ürün tablosunda variant adında bir sütun açıp bilgileri json olarak tutmak daha hızlı bir çözüm olmaz mı ? Deneyen var mı ?
Örneğin ben filtreleme kriterleri için hali hazırda @mgsmus örneklerindeki mantıkla çalışıyorum. Ancak şimdi ürün tablosunda feature adında bir sütun ekleyip [14,15,16,8,9] (14:5W, 15:10W, 16:20W, 8:Beyaz, 9:Siyah) benzeri özellik ID belirterek filtrelemeleri yazıyorum.
SELECT recordID,recordTitle,recordFeature FROM record WHERE JSON_CONTAINS(recordFeature, '[14,15]') bu şekilde basit bir sorgu ile de 5W ve 10W seçeneği olan ürünler
SELECT recordID,recordTitle,recordFeature FROM record WHERE JSON_CONTAINS(recordFeature, '[14]') OR JSON_CONTAINS(recordFeature, '[15]') bu şekilde de 5W veya 10W seçeneği olan ürünleri listeliyorum.
Performans olarak ne farklılık var üzerinde durmadım ama sql sorgusu ve yer yer içe içe döngü ile veri çekme çilesi yok gibi duruyor.
Bu konudaki fikirlerinizi merak ediyorum
Kaynak: http://www.erbilen.net/mysqlde-json-verileriyle-calismak/
fatihtorun RDMBS veritabanı kullanıyorsanız en rahat olacağınız yaklaşım şekli ilişkisel veri kullanmaktır. Oldu ki json içindeki bir alanın güncellenmesi gerekirse, 10 bin satırda geçiyorsa ya 10 bin satırı tek tek güncelleyeceksiniz ya bir kere yazıldı mı güncellenemez kuralı koyacaksınız ya da revizyon/versiyon sistemi geliştireceksiniz. Olaya sadece INSERT ve SELECT tarafından bakmayın; bu işin bir de UPDATE tarafı var.
Ayrıca RDMBS veritabanlarda json veri ile çalışmak sizi farklı indeksleme yöntemlerine, virtual column gibi yapılara yönlendirerek altyapının ilerledikçe karışmasına sebep olacaktır.
Benim tasviyem ilişkisel veri, kayıtlara ulaşmak için de ElasticSearch gibi 3. parti uygulamalar kullanmak. Ben JSON alanı sadece güncellenmeyeceğini düşünüyorsam ve ana başvuru kaynağım olmayacaksa kullanıyorum.
mgsmus Henüz düzgün bir sonuç olamadım ama mysql'e json olarak yazılmış verinin update, delete de mümkün görünüyor. Aşağıda bir örneği var.
İlk parametresi json verisi, 2. parametresi path yani yolu, 3. parametresi ise yeni değeri. Daha sonrasında path, value, path, value şeklinde devam ederek kullanılabilir.
UPDATE tablo_adi
SET kolon_adi = JSON_REPLACE(kolon_adi, '$.uye.ad', 'Tayfun')
Denemelerimde filtre seçeneklerini yönetim panelinden direk ilgili sütunu komple güncelliyorum. Spesifik olarak key belirterek de mevcut json verinin ilgili alanını da uptade/delete mümkün gibi. Tabi sanırım mysql 8 versiyon gerekiyor. Ben beceremedim
fatihtorun Ben uyarımı yaptım, gerisi size kalmış.
Merhabalar,
Admin tarafında e ticaret sayfası icin ürün galerisi yapmaya calısıyorum toplu ürün yüklerken tablodaki satır iki kere tekrar saglıyor toplu image yükledigim de bir den fazla row tekrarlıyorum bu arada kod ve görsel ekliyebilirim tüm kod tek sayfada tesekkürler emeginiz ve ilginiz icin
` $this->validate([
'title' => 'required',
'NewsImage.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048',
'product_id' => 'required',
]);
if(!empty($this->NewsImage)) {
foreach ($this->NewsImage as $image) {
$imageName = $image->hashName();
$image->store('public/products');
Image::create([
'title' => $this->title,
'image' => $imageName,
'product_id' => $this->product_id,
]);
}
}
$this->modalFormVisible = false;
$this->reset();
$this->resetFields();`
` @if(count($NewsImage))
@foreach($NewsImage as $image)
<td class="px-6 py-4 text-sm whitespace-no-wrap">
<img class="w-8 h-8 rounded-full" src="{{ \Illuminate\Support\Facades\Storage::url($Image->image) }}" />
</td>
@endforeach
@endif`
burakcoms Merhaba, foruma hoşgeldiniz. Sorunuz için yeni, ayrı bir konu açabilir misiniz?
Ayrıca düzgün kod paylaşımı ile ilgili şu sayfayı inceleyebilirsiniz:
https://laravel.gen.tr/d/4903-onemli-forumda-kod-paylasirken-dikkat-edilmesi-gerekenler