Как получить первичный ключ таблицы?


81

Есть ли способ получить имя поля первичного ключа из базы данных mysql? Например:

У меня есть такая таблица:

+----+------+
| id | name |
+----+------+
| 1  | Foo1 |
| 2  | Foo2 |
| 3  | Foo3 |
+----+------+

Если идентификатор поля является первичным ключом (он имеет автоматическое увеличение, но я не могу его использовать). Как я могу получить имя поля «id» в php?

Ответы:


135

Лучше использовать, SHOW KEYSпоскольку у вас не всегда есть доступ к information_schema. Следующие работы:

SHOW KEYS FROM table WHERE Key_name = 'PRIMARY'

Column_name будет содержать имя первичного ключа.


1
Хорошее предложение. information_schema поддерживается начиная с MySQL 5.0, но действительно этот метод работает и для более старых версий.
Роланд Боуман,

28
Есть ли способ получить только column_nameключ?
JDelage

используйте, cutесли хотите получить только имя столбца: `| cut -f5`
whoan

34

Вот имя столбца первичного ключа

SELECT k.column_name
FROM information_schema.table_constraints t
JOIN information_schema.key_column_usage k
USING(constraint_name,table_schema,table_name)
WHERE t.constraint_type='PRIMARY KEY'
  AND t.table_schema='YourDatabase'
  AND t.table_name='YourTable';

3
да - это один способ. В случае MySQL вы можете даже упростить это, потому что constraint_name всегда будетPRIMARY
Роланд Боуман,

не рекомендовал бы это вообще, это очень ресурс, требующий ответа Алексна намного быстрее
Breezer

да, этот запрос занимает много времени. то, что я сделал, - это еще одна таблица с именами таблиц и идентификаторами таблиц и попытка извлечь оттуда, если она не может найти таблицу, поэтому он делает этот длинный запрос и добавляет его в новую таблицу, работает намного быстрее. но ответ alexn тоже кажется действительно хорошим
Шир Ганс

2
Но это решение отлично работает при работе с несколькими таблицами. (Просто выберите k.table_name, k.column_name, k.ordinal_position).
Claus

21
SELECT kcu.column_name, kcu.ordinal_position
FROM   information_schema.table_constraints tc
INNER JOIN information_schema.key_column_usage kcu
ON     tc.CONSTRAINT_CATALOG = kcu.CONSTRAINT_CATALOG
AND    tc.CONSTRAINT_SCHEMA = kcu.CONSTRAINT_SCHEMA
AND    tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME
WHERE  tc.table_schema = schema()             -- only look in the current schema
AND    tc.constraint_type = 'PRIMARY KEY'
AND    tc.table_name = '<your-table-name>'    -- specify your table.
ORDER BY kcu.ordinal_position

1
Просто FYI, на SQLServer , constraint_nameвыглядит как UK_entity_name, PK_Users, и FK_Users_Contactsт.д., поэтому она не кажется , что можно доверять , чтобы иметь хорошо известную платформу агностик значение. 😞
Кристиан

1
Ого! Я не ожидал, что вы его обновите. 😅 Помимо нескольких вещей, он работает отлично! (Я обновил ваш ответ исправлениями, надеюсь, вы не против)
Кристиан

@Christian благодарит вас за быстрое наблюдение и исправление. Весьма признателен!
Роланд Боуман


7

Как насчет этого:

SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'Your Database'
  AND TABLE_NAME = 'Your Table name'
  AND COLUMN_KEY = 'PRI';


SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'Your Database'
  AND TABLE_NAME = 'Your Table name'
  AND COLUMN_KEY = 'UNI';

1
ОШИБКА 1054 (42S22): неизвестный столбец 'db' в 'where clause'
zloctb

1
@zloctb: А как насчет переименования dbвашей TABLE_SCHEMA ...? Я не понимаю, почему вы получили +1 за это ...
Людовик Гийом

1
Это был самый ясный из ответов, и он сразу сработал для меня.
Betty Mock

5

Если вы хотите динамически сгенерировать список первичных ключей с помощью PHP за один раз, не просматривая каждую таблицу, вы можете использовать

SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.key_column_usage 
WHERE table_schema = '$database_name' AND CONSTRAINT_NAME = 'PRIMARY' 

хотя для этого вам нужен доступ к information.schema.


2

Для подхода PHP вы можете использовать mysql_field_flags

$q = mysql_query('select * from table limit 1');

for($i = 0; $i < mysql_num_fields(); $i++)
    if(strpos(mysql_field_tags($q, $i), 'primary_key') !== false)
        echo mysql_field_name($q, $i)." is a primary key\n";

да, хорошее предложение. хоть и ограничен, но этого вполне достаточно для первых ключей.
Роланд Боуман,

Спрашивающий действительно сказал PHP.
arleslie

2

Кратчайший возможный код выглядит примерно так:

// $dblink contain database login details 
// $tblName the current table name 
$r = mysqli_fetch_assoc(mysqli_query($dblink, "SHOW KEYS FROM $tblName WHERE Key_name = 'PRIMARY'")); 
$iColName = $r['Column_name']; 

1

Наконец-то я понял!

<?php

function mysql_get_prim_key($table){
$sql = "SHOW INDEX FROM $table WHERE Key_name = 'PRIMARY'";
$gp = mysql_query($sql);
$cgp = mysql_num_rows($gp);
if($cgp > 0){
// Note I'm not using a while loop because I never use more than one prim key column
$agp = mysql_fetch_array($gp);
extract($agp);
return($Column_name);
}else{
return(false);
}
}

?>

0

Я использую SHOW INDEX FROM table; это дает мне много информации; если ключ уникален, его последовательность в индексе, сопоставлении, подчасти, если ноль, его тип и комментарий, если существует, см. снимок экрана здесьВот


Не могли бы вы подробнее рассказать о своем ответе, добавив еще немного описания предлагаемого вами решения?
abarisone

0

В MySQL есть SQL-запрос «SHOW INDEX FROM», который возвращает индексы из таблицы. Например, - следующий запрос покажет все индексы для таблицы продуктов: -

SHOW INDEXES FROM products \G

Он возвращает таблицу с типом, именем столбца, именем ключа и т.д. и отображает вывод со всеми индексами и первичными ключами как -

*************************** 1. row ***************************
        Table: products
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: product_id
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 

Чтобы просто отобразить первичный ключ из таблицы, используйте: -

SHOW INDEXES FROM table_name WHERE Key_name = 'PRIMARY'

Вы можете добавить объяснение, почему это отвечает на исходный вопрос.
Olivier De Meulder

0

Если в вашей базе данных есть пространственные таблицы, используйте:

SHOW KEYS FROM table WHERE Key_name = 'PRIMARY' OR Key_name = 'OGR_FID'

0

Вы должны использовать PRIMARY из key_column_usage.constraint_name = "PRIMARY"

образец запроса,

SELECT k.column_name as PK, concat(tbl.TABLE_SCHEMA, '.`', tbl.TABLE_NAME, '`') as TABLE_NAME
FROM information_schema.TABLES tbl
JOIN information_schema.key_column_usage k on k.table_name = tbl.table_name
WHERE k.constraint_name='PRIMARY'
  AND tbl.table_schema='MYDB'
  AND tbl.table_type="BASE TABLE";

0
SELECT k.column_name
FROM information_schema.key_column_usage k   
WHERE k.table_name = 'YOUR TABLE NAME' AND k.constraint_name LIKE 'pk%'

Я бы порекомендовал вам посмотреть все поля

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.