精华内容
下载资源
问答
  • 存在外键关联的主truncate如何做

    万次阅读 2015-06-09 08:42:30
    主外键是数据库提供的一种两表之间强制关联的方法,也可以从应用层实现。优点缺点数据库实现的主外键由数据库层机制保证,无需应用额外...存在主外键关联的主表,由于存在外键关联关系,因此有些操作就会禁止,例如trun

    主外键是数据库提供的一种两表之间强制关联的方法,也可以从应用层实现。


    优点
    缺点
    数据库实现的主外键
    由数据库层机制保证,无需应用额外实现
    强关联,不易扩展变更
    应用实现的主外键
    易扩展变更

    完全由应用控制,要求较高

    我认为需要根据实际情况进行取舍,例如表不复杂,可以由应用实现,若表之间关联较多且复杂,那么交由数据库处理,至少保证不会错。


    存在主外键关联的主表,由于存在外键关联关系,因此有些操作就会禁止,例如truncate。


    实验

    1. 创建测试表

    SQL> create table tbl_a(id number, remark varchar2(1));
    Table created.
    
    SQL> create table tbl_b(id number, a_id number, remark varchar2(1));
    Table created.
    
    SQL> alter table tbl_a add constraint pk_tbl_a primary key(id);
    Table altered.
    
    SQL> alter table tbl_b add constraint pk_tbl_b primary key(id);
    Table altered.
    
    SQL> alter table tbl_b add constraint fk_tbl_b_a foreign key(a_id) references tbl_a(id);
    Table altered.

    tbl_a是主表,tbl_b是子表,关联tbl_a。


    2. 现在主表和子表没有任何数据,此时执行truncate主表

    SQL> truncate table tbl_a;
    Table truncated.
    可以执行。


    3. 向主表插入一条记录,再次执行truncate

    SQL> insert into tbl_a values(1, 'a');
    1 row created.
    
    SQL> commit;
    Commit complete.
    
    SQL> truncate table tbl_a;
    truncate table tbl_a
    *
    ERROR at line 1:
    ORA-02266: unique/primary keys in table referenced by enabled foreign keys

    此时提示了ORA-02266:唯一/主键被启用的外键引用

    看看ORA-02266的解释:

    02266, 00000, "unique/primary keys in table referenced by enabled foreign keys"
    // *Cause: An attempt was made to truncate a table with unique or
    //         primary keys referenced by foreign keys enabled in another table.
    //         Other operations not allowed are dropping/truncating a partition of a
    //         partitioned table or an ALTER TABLE EXCHANGE PARTITION.
    // *Action: Before performing the above operations the table, disable the
    //          foreign key constraints in other tables. You can see what
    //          constraints are referencing a table by issuing the following
    //          command:
    //          SELECT * FROM USER_CONSTRAINTS WHERE TABLE_NAME = "tabnam";

    比较清楚地说明了问题,以及解决方法:可以在执行前,先禁用外键约束,执行truncate后再恢复外键约束。


    4. 禁用外键约束,删除后执行恢复操作

    看到外键约束名称:FK_TBL_B_A:

    SQL> select constraint_name, constraint_type, status from user_constraints where table_name='TBL_B';
    
    CONSTRAINT_NAME                C STATUS
    ------------------------------ - --------
    PK_TBL_B                       P ENABLED
    FK_TBL_B_A                     R ENABLED


    禁止外键约束:

    SQL> alter table tbl_b disable constraint FK_TBL_B_A;
    
    Table altered.
    
    SQL> select constraint_name, constraint_type, status from user_constraints where table_name='TBL_B';
    
    CONSTRAINT_NAME                C STATUS
    ------------------------------ - --------
    PK_TBL_B                       P ENABLED
    FK_TBL_B_A                     R DISABLED

    STATUS状态变为DISABLED了。


    truncate表:

    SQL> truncate table tbl_a;
    
    Table truncated.


    恢复约束:

    SQL> alter table tbl_b enable constraint FK_TBL_B_A;
    
    Table altered.
    
    SQL> select constraint_name, constraint_type, status from user_constraints where table_name='TBL_B';
    
    CONSTRAINT_NAME                C STATUS
    ------------------------------ - --------
    PK_TBL_B                       P ENABLED
    FK_TBL_B_A                     R ENABLED

    总结:

    1. 主外键是数据库提供的强约束,可以帮助我们控制主子表之间的关系,但同时还是一把双刃剑,当然,我们认为既然定义了主外键,就是需要这种强制关系,但有时可能就会有一些变更,因此,如何取舍,需要根据实际情况来决策。

    2. 主外键关联中的主表,如果有数据,则不能直接用truncate方式删除,因为会认为有外键和其关联,不能直接截断主表,若需要做,可以先禁止外键约束,主表变成一个独立的表,这样就可以执行truncate了。


    
    展开全文
  • 在MySql设定,其中product的主键设定成orderTb外键,具体如下: 产品: create table product(id INT(11) PRIMARY KEY,name VARCHAR(32) ); 订单: create table orderTb(id INT(11) PRIMARY ...

    在MySql设定两张表,其中product表的主键设定成orderTb表的外键,具体如下:

    产品表:

    create table product(id INT(11) PRIMARY KEY,name VARCHAR(32) );

     订单表:

    create table orderTb(id INT(11) PRIMARY KEY,productid INT(11), FOREIGN KEY(productid) REFERENCES product(id) );

     

    给产品表插入数据如下:

    给订单表插入数据如下:

    在MySql-Front工具中写SQL文“DELETE from product where id=1”,由于主外键关联,工具会如下报错:

     如果用java程序去删(工程下载:https://files.cnblogs.com/files/xiandedanteng/product191006_2.rar )

    删除代码:

    package com.hy;
    
    import java.io.Reader;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.apache.log4j.Logger;
    
    public class DeleteProductTest {
        private static Logger logger = Logger.getLogger(DeleteProductTest.class);
        
        public static void main(String[] args) throws Exception{
            long startTime = System.currentTimeMillis();
            Reader reader=Resources.getResourceAsReader("mybatis-config.xml");
            
            SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(reader);
            reader.close();
            
            SqlSession session=ssf.openSession();
            logger.info("Commit Status="+session.getConnection().getAutoCommit());
            
            try {
                ProductMapper pm=session.getMapper(ProductMapper.class);
                int changed=pm.deleteById(1);
                session.commit();
                logger.info("Committed! Chenged Record Num="+changed);
                
                long endTime = System.currentTimeMillis();
                logger.info("Time elapsed:" + toDhmsStyle((endTime - startTime)/1000) + ".");
            }catch(Exception ex) {
                logger.error("Error/Exception happened when executing the meothod'ProductMapper.deleteById(1)' because '"+ex.getMessage()+"'.");
                session.rollback();
                logger.info("Rollbacked.");
            }
            finally {
                session.close();
            }
        }
        
        // format seconds to day hour minute seconds style
        // Example 5000s will be formatted to 1h23m20s
        public static String toDhmsStyle(long allSeconds) {
            String DateTimes = null;
            
            long days = allSeconds / (60 * 60 * 24);
            long hours = (allSeconds % (60 * 60 * 24)) / (60 * 60);
            long minutes = (allSeconds % (60 * 60)) / 60;
            long seconds = allSeconds % 60;
            
            if (days > 0) {
                DateTimes = days + "d" + hours + "h" + minutes + "m" + seconds + "s";
            } else if (hours > 0) {
                DateTimes = hours + "h" + minutes + "m" + seconds + "s";
            } else if (minutes > 0) {
                DateTimes = minutes + "m" + seconds + "s";
            } else {
                DateTimes = seconds + "s";
            }
    
            return DateTimes;
        }
    }

    Mapper接口类

    package com.hy;
    
    public interface ProductMapper {
        int deleteById(long id);
    }

    Mapper.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
                        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="com.hy.ProductMapper">
        <delete id="deleteById">
            delete from product where id=#{id}
        </delete>
    </mapper>

    用程序强行去删,会出现异常:

    com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException

    执行下来,控制台输出会是:

     INFO [main] - Commit Status=false
    ERROR [main] - Error/Exception happened when executing the meothod'ProductMapper.deleteById(1)' because '
    ### Error updating database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`orderTb`, CONSTRAINT `orderTb_ibfk_1` FOREIGN KEY (`productid`) REFERENCES `product` (`id`))
    ### The error may involve defaultParameterMap
    ### The error occurred while setting parameters
    ### SQL: delete from product where id=?
    ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`orderTb`, CONSTRAINT `orderTb_ibfk_1` FOREIGN KEY (`productid`) REFERENCES `product` (`id`))'.
     INFO [main] - Rollbacked.

    因此,在删除时,应该有选择地辨认并跳过这种异常才行。具体程序如下:

     

    package com.hy;
    
    import java.io.Reader;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.apache.log4j.Logger;
    
    public class DeleteProductTest2 {
        private static Logger logger = Logger.getLogger(DeleteProductTest2.class);
        
        public static void main(String[] args) throws Exception{
            long startTime = System.currentTimeMillis();
            Reader reader=Resources.getResourceAsReader("mybatis-config.xml");
            
            SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(reader);
            reader.close();
            
            SqlSession session=ssf.openSession();
            logger.info("Commit Status="+session.getConnection().getAutoCommit());
            int totalChanged=0;
            
            try {
                ProductMapper pm=session.getMapper(ProductMapper.class);
                
                
                long[] arr= {1,2,3,4,5};
                for(long id:arr) {
                    logger.info("deleteById id="+id+" started!");
                    try {
                        int changed=pm.deleteById(id);
                        session.commit();
                        totalChanged+=changed;
                        logger.info("Committed! Chenged Record Num="+changed);
                    }catch(Exception ex) {
                        if(ex.getMessage().contains("foreign key constraint fails")){ // 用 ex instanceof 识别不出来,故而用这种方式
                            logger.error("ForeignKey collide Conflict happened when executing the meothod'ProductMapper.deleteById("+id+")'.");
                            continue;
                        }else {
                            logger.error("Other Error/Exception happened when executing the meothod'ProductMapper.deleteById("+id+")' because '"+ex.getMessage()+"'.");
                            session.rollback();
                            logger.info("Rollbacked.");
                        }
                    }
                    
                    logger.info("deleteById id="+id+" finished!");
                }
            }catch(Exception ex) {
                logger.error("Error/Exception happened when executing the meothod'ProductMapper.deleteById(1)' because '"+ex.getMessage()+"'.");
                session.rollback();
                logger.info("Rollbacked.");
            }
            finally {
                session.close();
            }
            
            logger.info("Changed recoed count="+totalChanged);
            long endTime = System.currentTimeMillis();
            logger.info("Time elapsed:" + toDhmsStyle((endTime - startTime)/1000) + ".");
        }
        
        // format seconds to day hour minute seconds style
        // Example 5000s will be formatted to 1h23m20s
        public static String toDhmsStyle(long allSeconds) {
            String DateTimes = null;
            
            long days = allSeconds / (60 * 60 * 24);
            long hours = (allSeconds % (60 * 60 * 24)) / (60 * 60);
            long minutes = (allSeconds % (60 * 60)) / 60;
            long seconds = allSeconds % 60;
            
            if (days > 0) {
                DateTimes = days + "d" + hours + "h" + minutes + "m" + seconds + "s";
            } else if (hours > 0) {
                DateTimes = hours + "h" + minutes + "m" + seconds + "s";
            } else if (minutes > 0) {
                DateTimes = minutes + "m" + seconds + "s";
            } else {
                DateTimes = seconds + "s";
            }
    
            return DateTimes;
        }
    }

    执行后输出如下:

     INFO [main] - Commit Status=false
     INFO [main] - deleteById id=1 started!
    ERROR [main] - ForeignKey collide Conflict happened when executing the meothod'ProductMapper.deleteById(1)'.
     INFO [main] - deleteById id=2 started!
    ERROR [main] - ForeignKey collide Conflict happened when executing the meothod'ProductMapper.deleteById(2)'.
     INFO [main] - deleteById id=3 started!
    ERROR [main] - ForeignKey collide Conflict happened when executing the meothod'ProductMapper.deleteById(3)'.
     INFO [main] - deleteById id=4 started!
     INFO [main] - Committed! Chenged Record Num=1
     INFO [main] - deleteById id=4 finished!
     INFO [main] - deleteById id=5 started!
     INFO [main] - Committed! Chenged Record Num=1
     INFO [main] - deleteById id=5 finished!
     INFO [main] - Changed recoed count=2
     INFO [main] - Time elapsed:10s.

     

    --END-- 2019年10月6日14:52:46

    转载于:https://www.cnblogs.com/xiandedanteng/p/11627144.html

    展开全文
  • 数据库的外键关联删除对象时相当的慢,会去查看每一个关联的的每条记录,...hibernate用条delete来完成同样的功能,如果数据库还存在外键的话,那么有一条delte是很慢的,我们手动把数据库的外键关联删除掉速度...

    数据库的外键关联删除对象时相当的慢,会去查看每一个关联的表的每条记录,这样当一个表被很多表引用时,删除这个表中的记录的代价是相当大的。hibernate的对象关联默认会在两个表之间做外键关联,而它的级联删除却没有用数据库的这种特性,这是个相当明智的决定。hibernate用两条delete来完成同样的功能,如果数据库还存在外键的话,那么有一条delte是很慢的,我们手动把数据库的外键关联删除掉速度就相当快了。

    这样我们在程序级别利用了级联的便利性,而性能上又没有什么损失。

     

    hibernate级联

    数据库不外键关联

    展开全文
  • 在B数据源也需要update-database,因为B数据源中的projectInfo 和该数据源中其他也有外键关联。在SQL Server 2008R2中为一个数据库。因此会报错:project已在。如下图![图片说明]...
  • mysql 创建 外键关联

    2010-09-10 11:03:11
    问题描述:最近在创建表间关联的时候报错 问题解决: ERROR 1005 (HY000): Can't create ...3、外键关联两表或多表要求都是INNODB类型的表;4、字段类型(说明)要一样`itemId` varchar(36) collate utf8_bi...

    问题描述:最近在创建表间关联的时候报错

    问题解决:

    ERROR 1005 (HY000): Can't create table ' ****.frm' (errno: 150)

    1、确保参照的表和字段是存在的;

    2、组成外键的字段要求被索引;

    3、外键关联的两表或多表要求都是INNODB类型的表;

    4、字段类型(说明)要一样`itemId` varchar(36) collate utf8_bin NOT NULL default '',

    5、确保以上声明的句法是正确的。

    error 1452(23000):cannot add or update a child row 

    表里有值,将对应的表清空

    展开全文
  • Python---mysql 外键关联

    千次阅读 2018-05-14 15:49:02
    外键关联:指利用外键将mysql中关联起来。1.创建study_record 注:key fk_student_key (stu_id) 表示与student创建关联符 stu_id 存在问题2.查看创建记录:3. 查看结构4. 添加数据注意 :在study_...
  • 在实际博客站点中,文章内容的数据量非常多,它...一对一关联有种方式,一种是外键关联。还有一种是复合主键关联。 外键关联 以下我们先看一个一对一单向关联的实例 /*************关联关系维护方*****...
  • 一篇文章的作者`author_id`可以设置外键关联`User`,同时文章的审稿人`reviewer_id`也可以设置外键关联`User`。当我们以SQLAchemy多对一(many to one)的设计方法来添加`relationship`关系映射时,程序会抛出一个...
  • 外键作为一种做用在表上的参照性约束,自然是要求表中所有纪录必须...这种关系的微妙之外在于,它即表明两表数据之间有“一定的”参照关系,但又不是必须的,它们也可以没有这种参照,显然,这表达的是一种更为宽松的
  • 外键:在存在一个共同的字段,且这个字段是其中一张的主键,此时这个字段称为另一张外键。 比如,教育机构和课程中都存在教育机构这个字段,且教育机构为教育机构的主键,此时教育...
  • 这个时候,我们可以尝试将文章内容存在另一张中,然后建立起文章——文章内容的一对一映射一对一关联有种方式,一种是外键关联,另一种是复合主键关联。外键关联下面我们先看一个一对一单向关联的实例/*********...
  • 刚来公司时看到很多都有一个valid_code字段,最开始还不懂是什么含义,问了同事才明白。...state有个状态表示数据是否存在,删除就是修改这个字段。 valid_code我们的规则是如果是有效数据我们设为0...
  • 上面篇博客介绍了cascade和inverse级联关系作用,而constrained属性是在主键映射一对一关系的时候会用到的一: 建立公民对象People与身份证对象IDcard一对一主键关联 公民与身份证关联关系 公民实体对象与...
  • 添加张已存在数据的的关系外键时,报如下图所示的错误: 出现这种错误,无非是关联字段的名称、类型、长度等不一致,又或者中已存在的数据不匹配造成的。 我们可以通过minus关键字查询2张表的差值...
  • #注意:要配置开启多条语句操作,否则会报错( org.apache.ibatis.exceptions.PersistenceException) ... lf-url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&...
  • 主外键是数据库提供的一种两表之间强制关联的方法,也可以从应用层...存在主外键关联的主表,由于存在外键关联关系,因此有些操作就会禁止,例如truncate。 SET FOREIGN_KEY_CHECKS=0; #取消外键约束 TRUNCATE TAB...
  • 【MySQL】创建外键种方式

    万次阅读 多人点赞 2019-02-19 10:55:21
    使用MySQL关联数据时,创建外键种方式:创建时增加外键,已存在表增加外键。以下案例通过Navicat for MySQL实现。 1.创建时增加外键 首先创建第一张被关联表Vendors商品供应商。 -- 供应商列表 ...
  • mysql外键约束

    2021-03-16 13:12:22
    对于个具有关联关系的而言,相关联字段中主键所在的就是主外键所在的就是从外键用来建立主与从关联关系,为的数据建立连接,约束中数据的一致性和完整性。 主删除某条记录时,...
  • MySQL外键

    2017-05-15 11:35:01
    若一个实体的某字段指向另一实体的主键,此字段即为外键。被指向的实体叫作主表,负责在指向的实体叫做从表。外键的作用用于约束处于关系内的...仅InnoDB存储引擎可以使用外键约束,外键的好处在于两表关联,保证...
  • 对于个通过外键关联,相关联字段中主键所在的是主,也称之为父,外键所在的是从,也称之为子,定义外键的时候需要遵守几个规则: 1、父必须已经存在于数据库中,或者是当前正在创建的。如果是...
  • 对于个通过外键关联,相关联字段中主键所在的是主,也称之为父,外键所在的是从,也称之为子,定义外键的时候需要遵守几个规则: 1、父必须已经存在于数据库中,或者是当前正在创建的。如果是...
  • 场景数据已经创建没有指定主外键,逻辑上存在外键关系,需要查询张有关系的数据案列这未指定主外键,其中user的depId为dep的主键,现在需要将姓名和部门展示。sql实现:select user.*,dep.* from ...

空空如也

空空如也

1 2 3 4 5 ... 15
收藏数 295
精华内容 118
关键字:

两表存在外键关联