mysql 虚拟主键_浅谈MySQL主键

主键没有着明确的概念定义,其是索引的一种,并且是唯一性索引的一种,且必须定义为“PRIMARY KEY”,是只可意会不可言传的东西。下面让我用通俗,甚至有些低俗的语言为您简单介绍一下MySQL的主键。

简单描述:

主键不能重复,就像QQ的用户名,有N个叫“虫zi”的网友,可是他们的QQ号码是不一样的,也就是说真正标识一个QQ的身份是“QQ号码”。

不过主键和QQ号不一样,因为一个表只能有一个主键,而一个人可以有多个QQ号,这也是为什么人们喜欢在虚拟世界里面互相忽悠,

貌似扯的有点远了,接着来看我们的MySQL主键。

声明主键的方法:您可以在创建表的时候就为表加上主键,如:CREATE TABLE tbl_name ([字段描述省略...], PRIMARY KEY(index_col_name));

也可以更新表结构时为表加上主键,如:ALTER TABLE tbl_name ADD PRIMARY KEY (index_col_name,…);

主键示例:

主键被认为是NOT NULL和UNIQUE约束最好的结合。如果这些列没有被明确地定义为NOT NULL,MySQL会隐含地定义这些列。

/*创建一个qq表,将qq_id设为主键,且没有对其进行NOT NULl约束*/create table qq(qq_id int(10),nick_name varchar(255) not null,primary key (qq_id))

/*插入一条数据,将qq号设为10000(咱也幻想一下),昵称设为"simaopig"*/INSERT INTO qq( qq_id, nick_name )VALUES ('10000', 'simaopig');

/*插入一条数据,qq号仍为10000,因为数据库内已经存在其10000这样的数据,而且最最主要的是其QQ号为主键,所以报错,信息如下#1062 - Duplicate entry '10000' for key 'PRIMARY'*/INSERT INTO qq( qq_id, nick_name )VALUES ('10000', 'chongpig')

/*虽然没有将qq号字段设NOT NULL约束,可是因为其是主键,所以其不能为NULL#1048 - Column 'qq_id' cannot be null*/INSERT INTO qq( qq_id, nick_name )VALUES (NULL , 'chongpig')

主键也是索引:

刚才已经说了,主键其实也是索引,甚至在MySQL的术语里面“键”就等于“索引”,所以“外键”一定要先设为“索引”,这个咱们下篇日志再来讨论。所以主键也应该和索引一样,既可以作用于单独的字段,又可以作用于多个字段。

举个简的例子吧,我住3单元,501室,我叫小小子,那么只有3单元501室才能在本小区表里面唯一确定我家。因为2单元,501室住着的可能也是个小小子,所以只有两个字段才能唯一确定我,也就是说可以二者组合作为主键。组合的主键,每个列都会隐含定义NOT NULL约束,且其二者加在一起被定义了UNIQUE 惟一约束。

例子不写自己想的了,书中举的例子更是恰当,那就是一个防火墙,由host和port组合确定一个防火墙。代码示例如下:

/*创建防火墙表,将host 和port组合设为主键,注意我没有将port设NOT NULL约束*/create table firewall(host varchar(11) not null,port smallint(4),access enum('deny', 'allow') not null,primary key (host,port))

/*插入一条新的记录,没有啥问题1 row(s) inserted.*/INSERT INTO firewall (host ,port ,access)VALUES ('202.65.3.87', '21', 'deny');

/*插入失败,因为host 加port的主键值202.65.3.87-21已经存在了#1062 - Duplicate entry '202.65.3.87-21' for key 'PRIMARY'*/INSERT INTO firewall (host ,port ,access)VALUES ('202.65.3.87', '21', 'allow');

/*没声明NOT NULl port也不能为NULL#1048 - Column 'port' cannot be null*/INSERT INTO firewall( host, port, access )VALUES ('192.168.0.1', NULL , 'deny')

在这个示例中,host和port都可以重复,但是不能同时重复,因为其是组合主键。且二者都不能被插入NULL,因为其是主键。

我们可以看一下phpmyadmin,看一下port字段的默认值为0,这和昨天我们讲的索引规则是一样的,NOT NULL并且给设了DEFAULT,因其是整型所以为0,如果其为字符串的话,默认值就是”

转载至:http://blog.csdn.net/hellosijian/article/details/7430492

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spark中,可以通过JDBC连接MySQL数据库并使用`upsert`语句来执行插入或更新操作。具体实现如下: 1. 导入必要的依赖: ```xml <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.23</version> </dependency> ``` 2. 创建一个`DataFrame`,并指定`DataFrame`的schema。假设需要将数据插入到名为`users`的MySQL表中,表结构如下: ```sql CREATE TABLE users ( id INT NOT NULL AUTO_INCREMENT, name VARCHAR(100), age INT, PRIMARY KEY (id) ); ``` 则可以定义如下的schema: ```scala import org.apache.spark.sql.types._ val schema = StructType(Seq( StructField("name", StringType), StructField("age", IntegerType) )) ``` 3. 读取数据并将其转换为`DataFrame`: ```scala val rdd = sc.parallelize(Seq( ("Alice", 25), ("Bob", 30), ("Charlie", 35) )) val df = spark.createDataFrame(rdd).toDF("name", "age") ``` 4. 将`DataFrame`写入到MySQL表中: ```scala val url = "jdbc:mysql://localhost:3306/mydb" val user = "username" val password = "password" df.write .format("jdbc") .option("url", url) .option("dbtable", "users") .option("user", user) .option("password", password) .option("driver", "com.mysql.jdbc.Driver") .option("rewriteBatchedStatements", "true") .option("batchsize", "10000") .mode("append") .save() ``` 在上述代码中,`url`用于指定MySQL数据库的连接地址,`user`和`password`用于指定数据库的用户名和密码,`dbtable`用于指定要写入的表名,`driver`用于指定MySQL的JDBC驱动程序。 `rewriteBatchedStatements`和`batchsize`用于优化写入性能。`rewriteBatchedStatements`设置为`true`时,表示使用批量写入模式,可以提高写入性能。`batchsize`用于指定每批次写入的记录数。 5. 如果需要执行`upsert`操作,则可以使用MySQL的`REPLACE INTO`语句或`ON DUPLICATE KEY UPDATE`语句。例如,如果需要根据`name`字段更新记录,则可以使用如下的SQL语句: ```sql INSERT INTO users (name, age) VALUES (?, ?) ON DUPLICATE KEY UPDATE age=VALUES(age) ``` 在Spark中,可以通过以下方式执行`upsert`操作: ```scala df.write .format("jdbc") .option("url", url) .option("dbtable", "users") .option("user", user) .option("password", password) .option("driver", "com.mysql.jdbc.Driver") .option("rewriteBatchedStatements", "true") .option("batchsize", "10000") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .option("rewriteBatchedStatements", "true") .mode("append") .jdbc(url, "users", prop) ``` 在上述代码中,`prop`是一个包含`user`和`password`属性的`java.util.Properties`对象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值