
mysql de çoka çok ilişki (MANY TO MANY) sorunsalı
5
●158
- 26-02-2023, 15:21:41Merhaba arkadaşlar, boş zamanlarımda uğraşmış olduğum bir proje var. Bu projede aşağıdaki resimde göreceğiniz üzere bir tablo yapım var. Örneğin bir resim yüklüyorum ve bu resime ait etiketleri kayıt ediyorum. Şimdi veri kaydetmede bir problem yok fakat sadece bir veriyi güncellerken yada tüm veriyi güncellerken bunu nasıl yapabilirim yada aynı şekilde silme işlemini yaparken nasıl yapabilirim bir türlü işin içerisinde çıkamadım yarımcı olabilirseniz çok sevinirim.

- 26-02-2023, 15:28:15Tablo yapınız güzel bu senaryo şöyle olabilir;
Tags' yönetimi panel üzerinde ayrı bir sayfada işlevselliği yapılabilir. Onları listelerken sadece bir yere bağlı olup olmadıklarına göz atılır.
Fotoğrafı eklerken yapmanız gereken düzenlerken silerken veya eklerken fark etmiyor.
DELETE FROM tagged WHERE photos_id = x
Kullanmanız yeterli olacaktır. Bu tablo zaten ilişkilendirme için
Fotoğrafları etiketleme yaptığınız input bir autocomplete olabilir daha önce eklenmiş olan etiketleri seçtirmek için.
Son olarak;
tags tablosundaki tags_slag mutlaka UNIQUE benzersiz olmalıdır bu tabloda etiket kesinlikle tekrar etmemeli.
Not:
Tagged içerisindeki tagged_id'ye gerek yok, o tablodan bir veri çıkarılırken WHERE tags_id = x AND photos_id = X
Öneri;
tablo adı "tags_relation" olabilir - 26-02-2023, 18:22:26Vakit ayırıp cevap verdiğiniz için teşekkür ederim. Önerilerinizi dikkate alacağım.QuarkChain adlı üyeden alıntı: mesajı görüntüle
1- Ayrı bir sayfada işlevsellikten kastınız şu mudur? Yani etiketler için ayrı bir sayfa yapıp etiketleri oradan ekleyip resim yüklerken de select box dan seçtirmek mi?
2- Dediğim gibi ekleme yaparken herhangi bir sıkıntı yok. Ama güncelleme sayfasında ilgili idye bağlı olan etiketleri input' a çektiriyorum örneğin bir resim'e ait 15 adete etiket mevcut bu etiketlerden 3 tanesini silmek yada düzenlemek istiyorum şimdi sizin dediğiniz mantıkta yaptığımızda photos_id yi baz aldığımızda bu sefer hepsi silinecek yada güncellenecek. (Yada bu kısmı tam olarak ben anlayamadım.) - 26-02-2023, 18:34:33Şu tarz bir input mu kullanıyorsunuz?

Diğer sayfada etiketlerin listelenmesinden kasıt şu, orada sadece hem ilişkili olduğu fotoğraflar görülebilir hem de ilgili etiketin kaç kez tıklandığına ve arandığına dair istatistiksel bilgiler yer alır.
Daha önce yaptığım örneklerden bir kod yapısı bulup gönderirim anlamanız için. Hepsi silinsin zaten inputtan gelen değerler yeniden tabloya dahil olacak. - 26-02-2023, 21:49:53Şöyle bir örnek yaptım size;


<?php $db = new mysqli('localhost', 'root', '', 'r10'); $db->query('SET NAMES utf8'); # Yeni fotoğraf ekle veya güncelle if ($_SERVER['REQUEST_METHOD'] == 'POST') { $photo_id = $_POST['id']; $photo_name = $_POST['photo_name']; $created_at = date('Y-m-d H:i:s'); // Ekle veya güncelle if ($photo_id) { $db->query("UPDATE photos SET photo_name = '{$photo_name}' WHERE photo_id = {$photo_id}"); } else { $db->query("INSERT INTO photos (photo_name, created_at) VALUES ('{$photo_name}', '{$created_at}')"); } // Düzenlenen bir fotoğraf ise önceki etiketleri boşaltalım if ($photo_id) { $db->query('DELETE FROM tags_relation WHERE photos_id = ' . $photo_id); } else { $photo_id = $db->insert_id; } // Etiketlerin düzenlenmiş halini yeniden ekleyelim $tags = json_decode($_POST['tags'], TRUE); foreach ($tags as $tag) { // Eğer etiket ID yok ise, yeniden oluşturalım if ( ! isset($tag['label'])) { $query = $db->query("INSERT INTO tags(tag_name) VALUES ('{$tag['value']}')"); $tag_id = $db->insert_id; } else { $tag_id = $tag['label']; } // İlişkilendirmek için ekle $db->query("INSERT INTO tags_relation(tags_id, photos_id) VALUES ({$tag_id}, {$photo_id})"); } // Sayfaya yönlendirelim header('Location: test.php'); exit(); } # Eski fotoğrafı sil # Etiket arama if (isset($_GET['term'])) { header('Content-type: application/json'); $term = stripslashes($_GET['term']); if (strlen($term) < 3) { exit(json_encode($array)); } $sql = "SELECT tag_id, tag_name FROM tags WHERE tag_name LIKE '%{$term}%' ORDER BY tag_name ASC LIMIT 5"; $query = $db->query($sql); $array = array(); while ($row = $query->fetch_object()) { $array[] = array('label' => $row->tag_id, 'value' => $row->tag_name); } exit(json_encode($array)); } ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Dashboard</title> <link href="https://fonts.googleapis.com/css?family=Fira+Sans:300,400,500,600,700,900&subset=latin-ext" rel="stylesheet" type="text/css" /> <link href="https://cdn.jsdelivr.net/npm/@yaireo/tagify/dist/tagify.css" rel="stylesheet" type="text/css" /> <style type="text/css"> body{font-family:Fira Sans} .tagify{width:100%;border-radius:4px} form{padding:20px;max-width:360px;margin:0 auto} .button button{width:100%;color:#fff;font:inherit;background-color:#000;border:0;box-sizing:border-box;font-size:13px;border-radius:3px;padding:10px 15px;height:38px;font-weight:500;cursor:pointer} .button button:hover{background-color:#222} .field label{display:block;margin-bottom:5px;margin-left:4px;color:#747474} .field{margin-bottom:1em;box-sizing:border-box} form .field:last-child{margin-bottom:0} .input{display:flex;align-items:center;border:1px solid #ced4da;border-radius:4px;overflow:hidden} .input textarea{border:0;box-sizing:border-box;padding:15px;font:inherit;resize:none;width:100%;min-height:60px} .input textarea:focus{outline:none} .input input{box-sizing:border-box;width:100%;border:0;font-size:13px;padding:0 15px;height:34px;line-height:34px;font:inherit} .input input::placeholder{color:#CCC} .input input:focus{outline:none} </style> </head> <body> <?php if (isset($_REQUEST['form'])): $input = (object) array( 'photo_name' => @$_POST['photo_name'], 'tags' => array() ); if ($_GET['form']) { $query = $db->query('SELECT * FROM photos WHERE photo_id = ' . (int) $_GET['form']); $row = $query->fetch_object(); $input->photo_name = $row->photo_name; $query = $db->query('SELECT tags.tag_id, tags.tag_name FROM tags_relation JOIN tags ON tags.tag_id = tags_relation.tags_id WHERE tags_relation.photos_id = ' . (int) $_GET['form']); while ($row = $query->fetch_object()) { $input->tags[] = array('label' => $row->tag_id, 'value' => $row->tag_name); } } ?> <!-- Fotoğraf Ekleme veya Düzenleme --> <form action="" method="POST"> <input type="hidden" name="id" value="<?php echo $_GET['form']; ?>"> <div class="form"> <div class="field"> <label>Fotoğraf Adı</label> <div class="input"> <input type="text" name="photo_name" value="<?php echo $input->photo_name; ?>"> </div> </div> <div class="field"> <label>Etiketler</label> <input type="text" name="tags" value='<?php echo json_encode($input->tags); ?>'> </div> <div class="button"> <button><?php echo ($_GET['form'] ? 'Değişiklikleri Kaydet' : 'Ekle'); ?></button> </div> </div> </form> <?php else: ?> <!-- Fotoğraf Listeleme --> <a href="?form">Yeni Fotoğraf</a> <main> <?php $query = $db->query('SELECT * FROM photos ORDER BY photo_id DESC'); ?> <table> <?php while ($row = $query->fetch_object()): ?> <tr> <td><?php echo $row->photo_id; ?></td> <td><?php echo $row->photo_name; ?></td> <td><?php echo 'x etiket'; ?></td> <td><a href="?form=<?php echo $row->photo_id; ?>">düzenle</a></td> </tr> <?php endwhile; ?> </table> </main> <?php endif; ?> <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.3/dist/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@yaireo/tagify"></script> <script src="https://cdn.jsdelivr.net/npm/@yaireo/tagify/dist/tagify.polyfills.min.js"></script> <script> var input = document.querySelector("input[name=tags]"), tagify = new Tagify(input, {whitelist:[], enforceWhitelist:false}), tagifController; tagify.on('input', function ( e ){ var value = e.detail.value; tagify.whitelist = null; tagifController && tagifController.abort(); tagifController = new AbortController(); tagify.loading(true).dropdown.hide(); fetch("?term=" + value, {signal: tagifController.signal}) .then(RES => RES.json()) .then(function(newWhitelist){ tagify.whitelist = newWhitelist; tagify.loading(false).dropdown.show(value); }); }); </script> </body> </html> - 27-02-2023, 10:40:51Çok teşekkür ederim vakit ayırdığınız için.QuarkChain adlı üyeden alıntı: mesajı görüntüle


