Ankündigung

Einklappen
Keine Ankündigung bisher.

Fremdschlüsselbeziehungen herausfinden

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Fremdschlüsselbeziehungen herausfinden

    Hallo,

    wie findet man eigentlich automatisiert Fremdschlüsselbeziehungen in MySQL-Tabellen heraus?

    MySQL :: MySQL 5.1 Referenzhandbuch :: 14.2.6.4 Fremdschlüssel-Beschränkungen
    Die Fremdschlüssel-Constraints einer Tabelle können wie folgt angezeigt werden:

    SHOW TABLE STATUS FROM db_name LIKE 'tbl_name';

    Die Fremdschlüssel-Constraints stehen in der Comment-Spalte der Ausgabe.
    Ja nur leider wird das COMMENT-Feld hier auf 80-Zeichen beschränkt (warum auch immer) und die Info wird einfach abgeschnitten:
    Code:
    ["Comment"]=>
        string(80) "InnoDB free: 773120 kB; (`td_bl_idBl`) REFER `*******/td_bl`(`idBl`) ON UPDATE C"
    SHOW FULL COLUMNS, SHOW KEYS hilft alles nichts, weil die Referenz darin nicht vermerkt ist.
    "Mein Name ist Lohse, ich kaufe hier ein."


  • #2
    Du könntest über die "Datenbank" information_schema gehen.
    Da stehen in REFERENTIAL_CONSTRAINTS alle Constraints drin, die du brauchst.

    // Tante Edit:
    Öhm...ja...oder auch nicht.
    Die Constraints stehen zwar drin, allerdings nur mit Tabellen, die Spalten fehlen.
    Musst halt slebst mal gucken, ob du in den restlichen Tabellen was passendes findest.
    VokeIT GmbH & Co. KG - VokeIT-oss @ github

    Kommentar


    • #3
      REFERENTIAL_CONSTRAINTS? Die Tabelle habe ich nicht.

      In information_schema.KEY_COLUMN_USAGE befinden sich diese Infos. Hatte ich auch vor, das für meine ActiveRecord-Klasse zu benutzen.

      EDIT villeicht benötigt man auch noch einen JOIN auf information_schema.TABLE_CONSTRAINTS, wegen des Constraints-Typs

      Kommentar


      • #4
        phpMyAdmin löst das wohl über SHOW CREATE TABLE `tableName` und parsed den String selbst. Problem:
        Mysqli prepare error: This command is not supported in the prepared statement protocol yet
        =>
        MySQL :: Re: "This command is not supported in the prepared statement protocol yet"
        Prepared statements are restricted to only a few category of statements. The type of queries that they work on is limited to DML (INSERT, REPLACE, UPDATE, and DELETE), CREATE TABLE, and SELECT queries. Support for additional query types will be added in further versions, to make the prepared statements API more general.
        Ich benutz Zend_Db_Adapter, jetzt muss ich wohl schauen, wie ich um die Prepared Statements drumherum schipper...

        Edit: Habs:
        PHP-Code:
        <?php
        /**
         * @var $db Zend_Db_Adapter_Mysqli
         */
        $mysqli $db->getConnection();
        $tableName "td_abtfirmax";
        $query "SHOW CREATE TABLE " $db->quoteIdentifier($tableName);
        var_dump($mysqli->query($query)->fetch_array());
        ?>
        Merci.
        "Mein Name ist Lohse, ich kaufe hier ein."

        Kommentar


        • #5
          Keine Ahnung, kann sein, dass meine Server-Version "zu neu" ist - 5.1.43 läuft hier.
          Ist ja auch wurscht, irgendwo in den Tabellen stehen jedenfalls alle Infos.
          VokeIT GmbH & Co. KG - VokeIT-oss @ github

          Kommentar


          • #6
            Zitat von G.Schuster Beitrag anzeigen
            Keine Ahnung, kann sein, dass meine Server-Version "zu neu" ist - 5.1.43 läuft hier.
            Ich habe Version 5.0.51 - gerade gelesen, die Tabelle gibt es ab 5.1.10

            Ist bei dir die Tabelle "KEY_COLUMN_USAGE" noch vorhanden, oder ist die weggefallen?

            Kommentar


            • #7
              Die gibt's noch.
              Hier mal alle Tabellen:
              Code:
              mysql> use information_schema;
              Database changed
              mysql> show tables;
              +---------------------------------------+
              | Tables_in_information_schema          |
              +---------------------------------------+
              | CHARACTER_SETS                        |
              | COLLATIONS                            |
              | COLLATION_CHARACTER_SET_APPLICABILITY |
              | COLUMNS                               |
              | COLUMN_PRIVILEGES                     |
              | ENGINES                               |
              | EVENTS                                |
              | FILES                                 |
              | GLOBAL_STATUS                         |
              | GLOBAL_VARIABLES                      |
              | KEY_COLUMN_USAGE                      |
              | PARTITIONS                            |
              | PLUGINS                               |
              | PROCESSLIST                           |
              | PROFILING                             |
              | REFERENTIAL_CONSTRAINTS               |
              | ROUTINES                              |
              | SCHEMATA                              |
              | SCHEMA_PRIVILEGES                     |
              | SESSION_STATUS                        |
              | SESSION_VARIABLES                     |
              | STATISTICS                            |
              | TABLES                                |
              | TABLE_CONSTRAINTS                     |
              | TABLE_PRIVILEGES                      |
              | TRIGGERS                              |
              | USER_PRIVILEGES                       |
              | VIEWS                                 |
              +---------------------------------------+
              28 rows in set (0.02 sec)
              VokeIT GmbH & Co. KG - VokeIT-oss @ github

              Kommentar


              • #8
                Der Quellcode für den Zend_Db_Adapter_Mysqli sieht jetzt so aus, $this->_db->listTables() gibt einen Array mit den Tabellennamen zurück.
                PHP-Code:
                <?php
                    
                public function getDatabaseTables()
                    {
                        
                $tables $this->_db->listTables();
                        
                $tables array_combine($tablesarray_fill(0count($tables), array(
                            
                "columns"     => array(),
                            
                "primaryKey"  => null,
                            
                "foreignKeys" => array(),
                            
                "uniqueKeys"  => array()
                        )));
                        foreach (
                $tables as $tableName => $tableInfo) {
                            
                // columns
                            
                $query "SHOW FULL COLUMNS FROM " $this->_db->quoteIdentifier($tableName);
                            
                $columnInfos $this->_db->fetchAll($query);
                            foreach (
                $columnInfos as $columnInfo) {
                                
                $tableInfo["columns"][] = $columnInfo["Field"];
                                switch (
                $columnInfo["Key"]) {
                                    case 
                "PRI":
                                        
                $tableInfo["primaryKey"]  = $columnInfo["Field"];
                                        break;
                                    case 
                "MUL":
                                        
                //$tableInfo["foreignKeys"] = $columnInfo["Field"];
                                        
                break;
                                    case 
                "UNI":
                                        
                $tableInfo["uniqueKeys"]  = $columnInfo["Field"];
                                        break;
                                    default:
                                }
                            }

                            
                // we can not use the adapter in this case, because of this error message:
                            // "Mysqli prepare error: This command is not supported in the prepared statement protocol yet"
                            
                $mysqli      $this->_db->getConnection();
                            
                $query       "SHOW CREATE TABLE " $this->_db->quoteIdentifier($tableName);
                            
                $createInfo  $mysqli->query($query)->fetch_assoc();
                            
                $createInfo  $createInfo["Create Table"];
                            
                $constraints explode(PHP_EOL$createInfo);
                            
                $constraints array_map("trim"$constraints);
                            
                $constraints array_filter($constraintscreate_function('$sql''return mb_strpos($sql, "CONSTRAINT ") === 0;'));
                            foreach (
                $constraints as $constraint) {
                                
                preg_match('/^CONSTRAINT `(.+)` FOREIGN KEY \(`(.+)`\) REFERENCES `(.+)` \(`(.+)`\)/'$constraint$matches);
                                
                $foreignKeyInfo = array(
                                    
                "name"      => $matches[1],
                                    
                "column"    => $matches[2],
                                    
                "reference" => array($matches[3], $matches[4])
                                );
                                
                $tableInfo["foreignKeys"][$matches[2]] = $foreignKeyInfo;
                            }

                            
                $tables[$tableName] = $tableInfo;

                        }
                        return 
                $tables;
                    }
                ?>
                "Mein Name ist Lohse, ich kaufe hier ein."

                Kommentar


                • #9
                  Oder so:
                  Code:
                  SELECT COLUMN_NAME, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME, CONSTRAINT_TYPE
                  FROM information_schema.KEY_COLUMN_USAGE AS k
                  INNER JOIN information_schema.TABLE_CONSTRAINTS USING(TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_NAME)
                  WHERE TABLE_SCHEMA = 'schema' AND TABLE_NAME = 'tabelle'
                  Wobei ich mir jetzt nicht ganz sicher bin, ob man nach CONSTRAINT_SCHEMA oder TABLE_SCHEMA abfragen sollte.
                  Aber Fremdschlüssel in anderen Datenbanken sind eher selten.

                  Kommentar

                  Lädt...
                  X