Проблема с флагом MySQLI MYSQL_PRI_KEY_FLAG

Я столкнулся с странным поведением и хочу знать, не ошибаюсь ли я, или API действительно работает именно так.

Я говорю о MYSQLI, мой собственный PHP-фреймворк может анализировать таблицу для создания динамического класса Entity, который работает очень хорошо до сих пор, однако я боюсь с MYSQLI_PRI_KEY_FLAG, который должен сказать мне, является ли индекс столбца частью индекса PRIMARY_KEY ,

Однако приведенная ниже таблица:

ip_ranges 

cols:

 account_id, min, max, comment 

Единственный индекс в этой таблице – уникальный индекс с именем:

 account_id_unique 

и более трех столбцов:

 account_id, min, max 

Определенно не определено PRIMARY_KEY.


До сих пор такая хорошая, последняя информация, которая вам нужна, это то, что в массиве $ this-> columns содержатся все данные столбцов, полученные с помощью:

 Mysqli_Result::fetch_fields 

Теперь я использую следующие 2 функции-члена, чтобы определить, имеет ли столбец флаг PRIMARY_KEY:

  public function columnHasFlag($columnName, $flag) { $retVal = false; if(isset($this->columns[strtolower($columnName)]) == true && $this->columns[strtolower($columnName)]["flags"] & $flag) { $retVal = true; } return $retVal; } public function determinePrimaryKeyColumn() { if($this->columnPrimaryKey === null) { foreach($this->columns as $columnName => $data) { if($this->columnHasFlag($columnName, MYSQLI_PRI_KEY_FLAG) == true) { $this->columnPrimaryKey = $columnName; break; } } } } 

Странно, что я получаю для приведенной выше таблицы примеров, когда я использую 'vardump' в $ this-> columns [strtolower ($ columnName)] ["flags"], который содержит флаги для столбца «account_id», он возвращает меня значение: "int (49155)"

и columnHasFlag возвращает значение true для оператора: $ this-> columns [strtolower ($ columnName)] ["flags"] & $ flag

($ flag оценивает константу MYSQLI_PRI_KEY_VALUE, которая оценивает значение «2».


Итак, как можно установить флаг? Я думал, что этот флаг установлен только для ключевого индекса PRIMARY, который должен иметь имя primary? Или он установлен для любого другого UNIQUE_KEY?

Однако это кажется довольно странным, потому что существуют отдельные флаги для UNIQUE и ключ PRIMARY в документации mysqli_result :: fetch_field:

 NOT_NULL_FLAG = 1 PRI_KEY_FLAG = 2 UNIQUE_KEY_FLAG = 4 ... (http://php.net/manual/en/mysqli-result.fetch-field.php) 

Итак, мой вопрос, это ошибка, или я неправильно сравниваю флаги? Или я пропустил что-то в документации?

Я не думаю, что это ошибка, вот цитата из Справочного руководства по MySQL

Индекс UNIQUE может отображаться как PRI, если он не может содержать значения NULL, и в таблице нет PRIMARY KEY. Индекс UNIQUE может отображаться как MUL, если несколько столбцов образуют объединенный индекс UNIQUE; хотя комбинация столбцов уникальна, каждый столбец все еще может содержать несколько вхождений заданного значения.

Это код, который я использовал для проверки этого поведения.

 $flags = array( 'NOT_NULL_FLAG' => MYSQLI_NOT_NULL_FLAG, 'PRI_KEY_FLAG' => MYSQLI_PRI_KEY_FLAG, 'UNIQUE_KEY_FLAG' => MYSQLI_UNIQUE_KEY_FLAG, 'MULTIPLE_KEY_FLAG' => MYSQLI_MULTIPLE_KEY_FLAG, 'BLOB_FLAG' => MYSQLI_BLOB_FLAG, 'UNSIGNED_FLAG' => MYSQLI_UNSIGNED_FLAG, 'ZEROFILL_FLAG' => MYSQLI_ZEROFILL_FLAG, 'BINARY_FLAG' => MYSQLI_BINARY_FLAG, 'ENUM_FLAG' => MYSQLI_ENUM_FLAG, 'AUTO_INCREMENT_FLAG' => MYSQLI_AUTO_INCREMENT_FLAG, 'TIMESTAMP_FLAG' => MYSQLI_TIMESTAMP_FLAG, 'SET_FLAG' => MYSQLI_SET_FLAG, 'PART_KEY_FLAG' => MYSQLI_PART_KEY_FLAG, 'NUM_FLAG' => MYSQLI_NUM_FLAG ); function info_array( $result ) { return array_reduce( $result->fetch_fields(), function( $result, $info ) { $result[ $info->name ] = $info; return $result; } ); } function get_flags( $meta, $flags ) { return array_filter( $flags, function( $flag ) use ( $meta ) { return $meta->flags & $flag; } ); } $result = $mysqli->query( 'SELECT * FROM ip_ranges LIMIT 1' ); $column_flags = array(); foreach( info_array( $result ) as $name => $value ) { $column_flags[ $name ] = get_flags( $value, $flags ); } print_r( $column_flags ); 

Таким образом, я создал таблицу в БД с уникальным индексом по 3 столбцам и получил выход, как вы сказали, все 3 столбца имеют установленный флаг первичного ключа.

 Массив (
     [account_id] => Массив (
          [NOT_NULL_FLAG] => 1
          [PRI_KEY_FLAG] => 2
          [PART_KEY_FLAG] => 16384
          [NUM_FLAG] => 32768)
     [min] => Массив (
          [NOT_NULL_FLAG] => 1
          [PRI_KEY_FLAG] => 2
          [PART_KEY_FLAG] => 16384
          [NUM_FLAG] => 32768)
     [max] => Массив (
          [NOT_NULL_FLAG] => 1
          [PRI_KEY_FLAG] => 2
          [PART_KEY_FLAG] => 16384
          [NUM_FLAG] => 32768)
     [комментарий] => Массив (
          [NOT_NULL_FLAG] => 1)

 )

Запрос столбцов show ( SHOW COLUMNS FROM ip_ranges ) в mysql admin SHOW COLUMNS FROM ip_ranges мне тот же результат.

 Тип поля Null Key Default Extra
 account_id int (11) NO PRI NULL    
 min int (11) NO PRI NULL    
 max int (11) NO PRI NULL    
 комментарий varchar () NO NULL    

Затем я создал первичный ключ и получил следующий вывод:

 Массив (
     [id] => Массив (
          [NOT_NULL_FLAG] => 1
          [PRI_KEY_FLAG] => 2
          [AUTO_INCREMENT_FLAG] => 512
          [PART_KEY_FLAG] => 16384
          [NUM_FLAG] => 32768)
     [account_id] => Массив (
          [NOT_NULL_FLAG] => 1
          [MULTIPLE_KEY_FLAG] => 8
          [PART_KEY_FLAG] => 16384
          [NUM_FLAG] => 32768
         )
     [min] => Массив (
          [NOT_NULL_FLAG] => 1
          [PART_KEY_FLAG] => 16384
          [NUM_FLAG] => 32768)
     [max] => Массив (
          [NOT_NULL_FLAG] => 1
          [PART_KEY_FLAG] => 16384
          [NUM_FLAG] => 32768)
     [комментарий] => Массив (
          [NOT_NULL_FLAG] => 1)
 )
 Тип поля Null Key Default Extra
 id int (11) NO PRI NULL auto_increment
 account_id int (11) NO MUL NULL    
 min int (11) NO NULL    
 max int (11) NO NULL    
 комментарий varchar () NO NULL    

Итак, в конце, php и mysql сообщают то же самое.