好。。。呵呵。多年来没有人提到一件微妙的事情。 尽管 DROP TABLE IF EXISTSbla; CREATE TABLEbla( ... ); 这似乎是合理的,它会导致一种情况,即旧表已经不存在,而新表尚未创建:一些客户机此时可能试图访问subject表。 更好的方法是创建全新的表并用旧表交换(表内容丢失):
CREATE TABLE `bla__new` (id int); /* if not ok: terminate, report error */
RENAME TABLE `bla__new` to `bla`; /* if ok: terminate, report success */
RENAME TABLE `bla` to `bla__old`, `bla__new` to `bla`;
DROP TABLE IF EXISTS `bla__old`;
CREATE VIEW `foo__new` as ...; /* if not ok: terminate, report error */
RENAME TABLE `foo__new` to `foo`; /* if ok: terminate, report success */
RENAME TABLE `foo` to `foo__old`, `foo__new` to `foo`;
DROP VIEW IF EXISTS `foo__old`;
旁注2:mariadb用户应该对 CREATE OR REPLACE TABLE/VIEW ,它已经关心了主题问题,这是很好的观点。
4条答案
按热度按时间pw136qt21#
只是放
DROP TABLE IF EXISTS
tablename;
在你的CREATE TABLE
声明。如果表存在,则该语句将删除该表,如果不存在,则不会抛出错误。
brqmpdu12#
我需要删除一个表并用视图中的数据重新创建。我用视图创建了一个表,我就是这么做的:
上面的方法对我使用mysql-mariadb是有效的。
bzzcjhmw3#
只是使用
DROP TABLE IF EXISTS
:如果您有任何其他问题,请先尝试搜索mysql文档。
dohp0rv54#
好。。。呵呵。多年来没有人提到一件微妙的事情。
尽管
DROP TABLE IF EXISTS
bla; CREATE TABLE
bla( ... );
这似乎是合理的,它会导致一种情况,即旧表已经不存在,而新表尚未创建:一些客户机此时可能试图访问subject表。更好的方法是创建全新的表并用旧表交换(表内容丢失):
你应该检查一下结果
CREATE ...
如果出现错误,请不要继续,因为失败意味着其他线程没有完成同一个脚本:或者是因为它在中间崩溃了,或者只是还没有完成——最好自己检查一下。然后,你应该先检查结果
RENAME ...
如果成功,不要继续:整个操作成功完成;更重要的是,下一个RENAME ...
如果另一个线程已经开始了相同的序列,则可能(也将)是不安全的(最好覆盖这个情况,而不是不覆盖,请参见下面的锁定注解)。第二
RENAME ...
原子替换表定义,详见mysql手册。最后,
DROP ...
显然,只是清理了旧table。将所有语句 Package 为
SELECT GET_LOCK('__upgrade', -1); ... DO RELEASE_LOCK('__upgrade');
允许只按顺序调用所有语句而不进行错误检查,但我认为这不是一个好主意:复杂性增加,mysql中的锁定函数对于基于语句的复制不安全。如果表数据在表定义升级后仍然有效。。。对于一般情况来说,比较表定义以找出差异并产生正确的结果要复杂得多
ALTER ...
语句,这并不总是可以自动执行的,例如在重命名列时。旁注1:在本例中,您可以使用相同的方法处理视图
CREATE/DROP TABLE
只是转变成CREATE/DROP VIEW
而RENAME TABLE
保持不变。事实上,你甚至可以把table变成视图,反之亦然。旁注2:mariadb用户应该对
CREATE OR REPLACE TABLE/VIEW
,它已经关心了主题问题,这是很好的观点。