如果表不存在则创建表之间的区别是什么,如果表在创建表之前就丢弃它们有什么区别?

时间:2016-12-29 17:55:10

标签: mysql sql database

我一直在研究数据库,并且遇到了drop table TABLE if exists语句的一些问题,以便不复制表。问题在于存在基于外键和包含依赖性的顺序(必须首先删除哪个表等)。但是还有其他一些语句允许创建一个表,如果它已经不存在create table table_name if not exists并且似​​乎在没有订单问题的情况下做同样的工作。 我只需要知道这两种处理方式之间是否存在差异,还有其他条件要考虑吗?

3 个答案:

答案 0 :(得分:2)

是的,有区别。如果表存在,CREATE TABLE IF NOT EXISTS nothing ,则不会产生任何冲突。

如果表存在,DROP TABLE IF EXISTS将丢弃表,如果需要表,则会导致冲突。

此外,正如其他人所说:   - 权限将被重置(如果是有意的话,这可能是一个加号;如果需要恢复权限,则可能是一个缺点)。   - 删除表时,所有数据都将丢失。   - 需要重新提交涉及该表的视图,过程,函数和索引。

由于所有这些原因,您可能不想使用DROP TABLE ,除非您不再需要所述表格。

如果这样做是为了将表重置为已知状态,这是数据库气味 - 这意味着您无法跟踪对数据库的更改。而不是解决问题,最好花一些时间来理解数据库失控的原因(您所做的任何更改都应该使用ALTER TABLE或CREATE INDEX进行,并且应该可以逐个撤消 1 ),以及如何将其重新置于控制之下。这将在未来产生巨大的回报。

在MySQL中,您可以SET FOREIGN_KEY_CHECKS = 0。请参阅here

(1)如果您的更改导致数据丢失,例如您将VARCHAR(30)更改为VARCHAR(15),则可以通过仅选择主键和受影响的字段来创建撤消表 - {{ 1}}在更改之前使用旧值。稍后,您可以更改字段定义,并在表格上执行CREATE TABLE undo_20161229_183415 AS SELECT tbl.pkey, tbl.changedfield1, tbl.changedfield2

注意:您可能希望首先添加WHERE以将旧值强制转换为新格式,并验证它是否与新表中的值匹配:

UPDATE JOIN

当您在2月2日想要展开并恢复数据时,您希望将2016-12-29.1 1234 PEOPLE'S REPUBLIC OF CHINA 2016-12-29.2 1234 PEOPLE'S REPUBLI # the change was ill advised 2017-01-15 1234 TAIWAN # the customer moved 替换为PRC的全名...... 除了在那条记录中您绝对不要我想把PRC恢复到现在的TAIWAN。

答案 1 :(得分:1)

删除然后创建将自然重置表的所有权限,以及使用此表的查询的执行计划。使用此表的所有过程/函数也将失效。

答案 2 :(得分:0)

通常在释放数据库更新时,它会被用来编写带有用于创建表或其他对象的语句的sql脚本。

从这里你可以遵循几种策略。 Mysql似乎也支持创建一个附加更新的脚本文件的策略,因此只有在第一次执行脚本时才创建表,以下所有执行都不会创建表。当然,在这种情况下,您将添加" [Service(Name="com.sample.evolve.GcmService")] //Must use the service tag public class GcmService : GcmServiceBase { . . . protected override void OnMessage (Context context, Intent intent) { Console.WriteLine ("Received Notification"); try { //Push Notification arrived - print out the keys/values if (intent != null || intent.Extras != null) { var keyset = intent.Extras.KeySet (); foreach (var key in keyset) { var message = intent.Extras.GetString(key); Console.WriteLine("Key: {0}, Value: {1}", key, message); if(key == "message") await PushNotificationHelpers.ShowAlert(message); } } } catch(Exception ex) { Console.WriteLine ("Error parsing message: " + ex); } } } "子句到脚本文件的所有对象。

相反,更加遵循的策略是创建多个文件,与db对象一样多,每个对象一个文件。因此,如果对象是一个表,那么首先创建表将其删除(如果存在),并解释另一个语句。

当然,当您执行此表脚本文件时,您需要密切关注要保留丢失的数据库数据,以及由于最终可能影响删除操作的外键约束而执行的执行顺序。 / p>

通常,此脚本仅在开发或测试环境中启动,或者在生产中首次安装数据库时启动。

通常,在prod env中,就更新db表对象而言,获取仅包含alter语句的已启动脚本。