Jörg Schumann: gegebene Datenbank mit Json-Eintag auslesen und Auswahl anzeigen

Hallo Leute,
Vorab: habe schon reichlich gesucht und probiert und immer nur den Hinweis bekommen, die Datenbank sei nicht i.O. sie müsse normalisiert werden.
Die Datenbank ist aber nun mal so gegeben und nicht von mir.
zu meinem Problem:
Die Datenbank besteht aus normalen Inhalten und einem mit dem Inhalt in Form eines Json.
genau da drinn stehen nun die von mir benötigten Daten.
Hier mal die Datenbank:

  
CREATE TABLE IF NOT EXISTS `gw2_items` (  
  `id` MEDIUMINT(6) unsigned NOT NULL,  
  `signature` varchar(40) COLLATE utf8_bin NOT NULL,  
  `file_id` int(10) unsigned NOT NULL DEFAULT '0',  
  `rarity` enum('Junk','Basic','Fine','Masterwork','Rare','Exotic','Ascended','Legendary') COLLATE utf8_bin NOT NULL DEFAULT 'Junk',  
  `weight` enum('None','Clothing','Light','Medium','Heavy') COLLATE utf8_bin NOT NULL DEFAULT 'None',  
  `type` enum('None','Armor','Back','Bag','Consumable','Container','CraftingMaterial','Gathering','Gizmo','MiniPet','Tool','Trinket','Trophy','UpgradeComponent','Weapon') COLLATE utf8_bin NOT NULL DEFAULT 'None',  
  `subtype` tinytext COLLATE utf8_bin NOT NULL,  
  `unlock_type` tinytext COLLATE utf8_bin NOT NULL,  
  `level` tinyint(2) unsigned NOT NULL DEFAULT '0',  
  `value` MEDIUMINT(6) unsigned NOT NULL DEFAULT '0',  
  `pvp` tinyint(1) unsigned NOT NULL DEFAULT '0',  
  `attr_name` tinytext COLLATE utf8_bin NOT NULL,  
  `unlock_id` MEDIUMINT(6) unsigned NOT NULL DEFAULT '0',  
  `name_de` tinytext COLLATE utf8_bin NOT NULL,  
  `name_en` tinytext COLLATE utf8_bin NOT NULL,  
  `name_es` tinytext COLLATE utf8_bin NOT NULL,  
  `name_fr` tinytext COLLATE utf8_bin NOT NULL,  
  `data_de` text COLLATE utf8_bin NOT NULL,  
  `data_en` text COLLATE utf8_bin NOT NULL,  
  `data_es` text COLLATE utf8_bin NOT NULL,  
  `data_fr` text COLLATE utf8_bin NOT NULL,  
  `wikipage_de` int(10) unsigned NOT NULL DEFAULT '0',  
  `wikipage_en` int(10) unsigned NOT NULL DEFAULT '0',  
  `wikipage_es` int(10) unsigned NOT NULL DEFAULT '0',  
  `wikipage_fr` int(10) unsigned NOT NULL DEFAULT '0',  
  `wiki_de` tinyint(1) unsigned NOT NULL DEFAULT '0',  
  `wiki_en` tinyint(1) unsigned NOT NULL DEFAULT '0',  
  `wiki_es` tinyint(1) unsigned NOT NULL DEFAULT '0',  
  `wiki_fr` tinyint(1) unsigned NOT NULL DEFAULT '0',  
  `wiki_checked` tinyint(1) unsigned NOT NULL DEFAULT '0',  
  `updated` tinyint(1) unsigned NOT NULL DEFAULT '0',  
  `update_time` int(10) unsigned NOT NULL DEFAULT '0',  
  `date_added` int(10) unsigned NOT NULL DEFAULT '0',  
  PRIMARY KEY (`id`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

der Inhalt von data_de beinhaltet den Json String den ich benötige.:

{"item_id":"73","name":"Duellanten-Maske des Berserkers der Dwayna","description":"","type":"Armor","level":"70","rarity":"Exotic","vendor_value":"295","icon_file_id":"561548","icon_file_signature":"65A0C7367206E6CE4EC7C8CBE07EABAE0191BFBA","game_types":["Activity","Dungeon","Pve","Wvw"],"flags":["SoulBindOnUse"],"restrictions":[],"armor":{"type":"Helm","weight_class":"Medium","defense":"81","infusion_slots":[],"infix_upgrade":{"attributes":[{"attribute":"Power","modifier":"37"},{"attribute":"Precision","modifier":"26"},{"attribute":"CritDamage","modifier":"2"}]},"suffix_item_id":"24768"}}

wie kann ich nun diesen String bzw. relevante Teile ausgeben und die Ausgabe sortieren?

Danke für eure Hilfe.

  1. wie kann ich nun diesen String bzw. relevante Teile ausgeben und die Ausgabe sortieren?

    Mit SQL wird das wohl nicht möglich sein nach dem relevanten zu sortieren, oder nur _sehr_ umständlich.

    Da ich nicht weiß, was die Filterkretierien sind und was nun der relevante Teil des JSON-Strings ist, kann ich aber auch nichts genaueres sagen.

    MfG
    bubble

    --
    If "god" had intended us to drink beer, he would have given us stomachs. - David Daye
    1. relevant wären für mich:
      "description":"flags":"restrictions":{"type":"Helm","weight_class":"Medium","defense":"81","infusion_slots":[],"infix_upgrade":{"attributes":[{"attribute":"Power","modifier":"37"},{"attribute":"Precision","modifier":"26"},{"attribute":"CritDamage","modifier":"2"}]},"suffix_item_id":"24768"}}

      Die Sortierung und Auswahl kann ich auch über die anderen Datenbankeinträge machen.
      es geht im Grunde nur um die Ausgabe einzelner Daten des Json-Strings.

      1. So ich habe nun mal die Abfrage soweit fertig gestellt:

          
        <?php  
        $verbindung = mysql_connect ("localhost",  
        "root", "17111970")  
        or die ("keine Verbindung möglich.  
         Benutzername oder Passwort sind falsch");  
          
        mysql_select_db("gw2")  
        or die ("Die Datenbank existiert nicht.");  
        ?>  
        <table>  
        <?php  
        $abfrage = "SELECT * FROM gw2_items WHERE subtype LIKE 'Food'  ORDER BY name_de ";  
          
        $ergebnis = mysql_query($abfrage);  
          
        while($row = mysql_fetch_object($ergebnis))  
        	  
           {  
          
        	   ?>  
               <tr>  
               <td>  
               <?php  
        	   echo $row->name_de  
        	   ?>  
               <td>  
               <td>  
               <?php  
        	   echo "<img src=https://render.guildwars2.com/file/$row->signature/$row->file_id>"  
        	   ?>  
               <td>  
               <td>  
               <?php  
        	   echo $row->level  
        	   ?>  
               <td>  
               <td>  
               <?php  
        	   echo   $row->data_de  
        	   ?>  
          </td>  
          </tr>  
          <?php  
        }  
        ?>  
        </table>  
        <?php  
        mysql_close($verbindung);  
        ?>
        

        Das Image setzt sich aus der signatur und der file_id zusammen und wird angezeigt, alles kein Problem.

        Nur nach wie vor fehlt mir jeder Ansatz aus den Daten von data_de mir nur die Werte
        "game_types":["Dungeon","Pve","Wvw"],"flags":["NoSell"],"restrictions":[],"consumable":{"type":"Food","duration_ms":"900000","description":"Erhaltet jede Sekunde Lebenspunkte.
        +10 Erfahrung f\u00fcr besiegte Gegner"}}

        aus

        {"item_id":"12309","name":"Apfeltorte","description":"","type":"Consumable","level":"5","rarity":"Basic","vendor_value":"4","icon_file_id":"63351","icon_file_signature":"CE6D4005CA07770BF8FB96FC060FF227FE47CBBC","game_types":["Dungeon","Pve","Wvw"],"flags":["NoSell"],"restrictions":[],"consumable":{"type":"Food","duration_ms":"900000","description":"Erhaltet jede Sekunde Lebenspunkte.
        +10 Erfahrung f\u00fcr besiegte Gegner"}}

        anzeigen zu lassen.

  2. wie kann ich nun diesen String bzw. relevante Teile ausgeben und die Ausgabe sortieren?

    In der Datenbank glaub ich ist das nicht möglich (korrigiert mich wenn ich unrecht habe). Es gibt DB-Systeme mit JSON-Support wie zb DB2, aber was die genau anbieten weiß ich nicht.

    Je nach Sprache müsstest du das somit im Code selber machen, dir also die JSON Daten holen, umdekodieren (z.B. in PHP mit : http://www.php.net/manual/de/function.json-decode.php) und selbst sortieren.

    lg

    1. @ms88,
      es soll nicht in der DB gemacht werden.
      Es soll einfach nur eine Art Tabelle ausgegeben werden mit einem Teil Inhalt der DB sortiert bzw. ausgewählte (gefilterte) Elemente.

      Quasi  in Form:

      Name | Level | und so weiter| (aus der DB)  ||  flags | restrictions | type (aus dem Jsonstring)

      Sprich klartexte aus der DB mit decodiertem Teil aus der Json die in der Datenbank liegen.

      1. @ms88,
        es soll nicht in der DB gemacht werden.
        Es soll einfach nur eine Art Tabelle ausgegeben werden mit einem Teil Inhalt der DB sortiert bzw. ausgewählte (gefilterte) Elemente.

        Quasi  in Form:

        Name | Level | und so weiter| (aus der DB)  ||  flags | restrictions | type (aus dem Jsonstring)

        Sprich klartexte aus der DB mit decodiertem Teil aus der Json die in der Datenbank liegen.

        Also ich wüsst im Moment nur den Ansatz, dass du normal die Felder selektierst die du benötigst + die json encodierte Spalte, und anschließend in einer Schleife die Daten manuell decodierst und Speicherst oder direkt schon ausgibst, also in pseudocode ähnlich:

        Achtung syntax ist nicht 100%tig korrekt:

        $new_array() = array();  
        $res = $sql->select(STATEMENT);  
        while ($tmp = $res->fetch(ASSOC)) {  
           $tmparray["spalte1"] = $tmp["spalte1"];  
           $tmparray["spalte2"] = $tmp["spalte2"];  
           ...  
           $decoded = json_decode($tmp["jsonspalte"], true);  
           $tmparray["spalte_jsonproperty1"] = $decoded["property1"];  
           ...  
           $new_array[] = $tmparray;  
        }
        
  3. Hallo,

    die DB sollte dir mit etwas ähnlichem wie
    select data_de from gw2_items
    die als String gespeicherten JSONs liefern.
    Da sie aber nicht weiß, dass da noch unterschiedliche Felder drinstecken, muss dein Script das wieder aufdrüseln und selber filtern und sortieren.

    Übrigens ist die Datenbank nicht i.O. und müsste normalisiert werden.

    Gruß
    Kalk

    1. Ja das mit dem Normalisieren habe ich zur Genüge gehört, ist mir so aber nicht möglich, da diese gegeben ist und regelmäßig aktualisiert wird.
      Die Datenbank wird aus zwei API´s gefüllt.
      Die eine Api gibt die vorhandenen Id´s der Items wieder, die Ander die Details der Items.
      Die ganze Prozedur kann ich leider nicht beeinflussen, da diese nicht von mir stammen.

      Eigene Datenbank inklusive der aktualisierung ist mir ne Nummer zu groß.
      Das wäre natürlich besser, nur die relevanten Dinge klar in die Datenbank zu setzen, dazu bin ich aber nicht fit genung.

      Hier mal die Api Adressen:

      https://api.guildwars2.com/v1/items.json

      Hier kommen die vorhandenen Items-Id´s her

      https://api.guildwars2.com/v1/item_details.json?item_id=30704&lang=de

      Hier kommen die dazugehörigen Details her.

      Die ID müsste quasi von der items.json genommen werden.

      Der jene welcher die Datenbankgeschicht programmiert hat erledigt dieses mit PHP und befüllt damit die Mysql-Datenbank.