MySQL 将列更改为 table 中的最后一个位置
MySQL ALTER column to last position in table
我正在与一位客户合作,他希望大型数据库中的每个 table 都有每条记录的历史数据,并且为了美观,希望这些列位于每个 [=47] 的末尾=].例如:
Table 姓名
- 主键
- 数据列
- 历史专栏
所以我的问题是,是否有 SQL 命令将列移动到 table 的末尾?我更愿意编写一个存储过程以按预定顺序将每个历史记录列移动到最后一个位置,但唯一的命令 MySQL 似乎只有 FIRST 和 AFTER,没有 LAST 选项。
除了查询序号最高的列的 information_schema table 并将其移动到它之后之外,是否有解决此问题的简单方法?
编辑
我目前的解决方案是找到最底部的一行:
SELECT column_name FROM information_schema.columns
WHERE table_name = tableName AND table_schema = currentSchema
AND ordinal_position IN
(SELECT max(ordinal_position) FROM information_schema.columns
WHERE table_name = tableName AND table_schema = currentSchema
AND column_name <> 'first_history_column'
GROUP BY table_name);
然后按如下顺序排列:
ALTER TABLE tableName MODIFY 'first_history_column' AFTER column_name;
ALTER TABLE tableName MODIFY 'second_history_column' AFTER 'first_history_column';
etc...
是否有比当前解决方案更快的方法?
要移动列,您必须复制它。
ALTER TABLE test ADD history_new VARCHAR(60)
将在 table 的末尾插入一个新列。
UPDATE test SET history_new=history_old
会将值从旧列复制到新列。并且
ALTER TABLE test DROP history_old
将删除旧列。
编辑
只是给出一个我之前没有想到的替代方案:
ALTER TABLE test ADD dummy TINYINT(1)
在 table 的末尾插入一个虚拟列,只是因为您知道名称。
ALTER TABLE test MODIFY first_history_column AFTER dummy
ALTER TABLE test DROP dummy
然后将您的历史记录列移到虚拟项之后并将其删除。所以只有 3 个 ALTER TABLES 而没有更新。
如果您可以搜索您的历史记录列,为什么不在 table
中将所有不是历史记录列的列都放在第一位
SELECT column_name FROM information_schema.columns
WHERE table_name = tableName AND table_schema = currentSchema
AND column_name NOT LIKE '%history%' and table_name = tableName
然后在table中先做主键。
SELECT k.COLUMN_NAME
FROM information_schema.table_constraints t
LEFT JOIN information_schema.key_column_usage k
USING(constraint_name,table_schema,table_name)
WHERE t.constraint_type='PRIMARY KEY' and table_name = tableName
我正在与一位客户合作,他希望大型数据库中的每个 table 都有每条记录的历史数据,并且为了美观,希望这些列位于每个 [=47] 的末尾=].例如:
Table 姓名
- 主键
- 数据列
- 历史专栏
所以我的问题是,是否有 SQL 命令将列移动到 table 的末尾?我更愿意编写一个存储过程以按预定顺序将每个历史记录列移动到最后一个位置,但唯一的命令 MySQL 似乎只有 FIRST 和 AFTER,没有 LAST 选项。
除了查询序号最高的列的 information_schema table 并将其移动到它之后之外,是否有解决此问题的简单方法?
编辑
我目前的解决方案是找到最底部的一行:
SELECT column_name FROM information_schema.columns
WHERE table_name = tableName AND table_schema = currentSchema
AND ordinal_position IN
(SELECT max(ordinal_position) FROM information_schema.columns
WHERE table_name = tableName AND table_schema = currentSchema
AND column_name <> 'first_history_column'
GROUP BY table_name);
然后按如下顺序排列:
ALTER TABLE tableName MODIFY 'first_history_column' AFTER column_name;
ALTER TABLE tableName MODIFY 'second_history_column' AFTER 'first_history_column';
etc...
是否有比当前解决方案更快的方法?
要移动列,您必须复制它。
ALTER TABLE test ADD history_new VARCHAR(60)
将在 table 的末尾插入一个新列。
UPDATE test SET history_new=history_old
会将值从旧列复制到新列。并且
ALTER TABLE test DROP history_old
将删除旧列。
编辑
只是给出一个我之前没有想到的替代方案:
ALTER TABLE test ADD dummy TINYINT(1)
在 table 的末尾插入一个虚拟列,只是因为您知道名称。
ALTER TABLE test MODIFY first_history_column AFTER dummy
ALTER TABLE test DROP dummy
然后将您的历史记录列移到虚拟项之后并将其删除。所以只有 3 个 ALTER TABLES 而没有更新。
如果您可以搜索您的历史记录列,为什么不在 table
中将所有不是历史记录列的列都放在第一位SELECT column_name FROM information_schema.columns
WHERE table_name = tableName AND table_schema = currentSchema
AND column_name NOT LIKE '%history%' and table_name = tableName
然后在table中先做主键。
SELECT k.COLUMN_NAME
FROM information_schema.table_constraints t
LEFT JOIN information_schema.key_column_usage k
USING(constraint_name,table_schema,table_name)
WHERE t.constraint_type='PRIMARY KEY' and table_name = tableName