【Linux】 MySQL

1 篇文章 0 订阅

安装

命令如下:

$ sudo apt-get install mysql-server
$ sudo apt-get install mysql-client
$ sudo apt-get install libmysqlclient-dev

其中查看当前mysql是否开启:

$ netstat -tap | grep mysql

开启mysql:

$ mysql -u username -p 
Enter password: 

编码

创建新用户:

GRANT ALL ON *.* TO **LETENO** IDENTIFIED BY 'PASSWORD';
创建用户LETENO, 密码PASSWORD,赋予的权限是:all

(all 这个应该是跟操作grant的用户有关,如果是root,则为root权限)

ON *.* 表示所有表,第一个* 应该表示数据库?抑或是创建数据库的人?(待考证,应该是前者), 
因为记得在Oracle中识别一个表需要的不仅仅是表名,还有创建者,如leteno.student_list(难不成Oracle是用创建表的用户作为表所存的数据库名(命名空间?)))

//2015.06.07
*.*,第一个*表示数据库名。

创建数据库:

CREATE DATABASE LETENO_DB;
USE LETENO_DB
创建数据库LETENO_DB,以及切换到LETENO_DB数据库。

创建表:

CREATE TABLE student ( 
    sno int(11) NOT NULL auto_increment, 
    sname varchar(30), 
    age int(11), 
    PRIMARY KEY (sno) 
);

注意:此处的auto_increment,本人尝试过一开始直接添加学生的sno=100,接下来默认添加的学生的sno为101 102… 又再添加学生sno为1,默认添加的学生为103 104…
要想重置auto_increment:

ALTER TABLE student AUTO_INCREMENT=1;

貌似这个还要看mysql的类型,我的不能用。。。
看来还是oracle比较底层,可以操纵sequence实现increment的起始,步长等。(可能还没学到mysql内部的操作)

类型

此处仅列举标准SQL类型,目的是为了标准化,规范化。

类型关键字注意事项
布尔BOOL取值有TRUE FALSE NULL
字符CHAR CHAR(N) VARCHAR(N)VARCHAR是可变长数组,而CHAR得恰好有N个字符。
数值INT DOUBLE NUMERIC(P,S)P代表总共有多少位数字,S代表其中小数部分多少位。比double精确,效率会较慢,毕竟得检查。
时间DATE DATETIME TIME TIMESTAMP常见的是TIMESTAMP 存储1970 - 2037年之间的时间戳(时间这么短,原因1,用32位存储;*原因2,时间用秒计),注意使用DATE DATETIME得小心,最好先查阅手册
自增长AUTO_INCREMENT只能是主键的属性
空值NULL 、 NOT NULL色即是空空
主键PRIMARY KEY其物理含义是该字段是唯一的,不存在相同的

增删改查:

INSERT INTO student (sno, sname, age) VALUES (1, 'leteno', 13);
DELETE FROM student WHERE SNAME=‘TEMP’;
UPDATE student SET AGE = 18 WHERE SNO=2;
SELECT * FROM student WHERE SNAME='LETENO';

*1)增加的还有另外一种方式:
INSERT INTO student values(1, ‘leteno’, 13);
不过不常用,它里面的属性值必须一一对应,而且不得缺漏(否则,会报:Column count doesn’t match value count)
*2)表名的大小写敏感,也就是STUDENT 会报:Table ‘LETENO_DB.STUDENT’ does not exist(.前面是数据库的名字。。。),(*但是列名确是大小写不分,age与AGE,而且连字段值也不分大小写,leteno与LETENO)
**3)使字段值区分大小写:(对字段添加一个binary属性)

1)创建时: ... sname varchar(30) binary, ...
2)ALTER TABLE student MODIFY COLUMN sname varchar(30) BINARY;

进阶:

mysql命令

这些命令在shell中执行,mysql命令可以在 mysql> 中执行,这些命令在shell中都有选项-u < .username > -p <.password>(password 一般不连同指令一块出现,不安全,一般省去,在下面noecho输入),一般当你输入下面的命令时都会被deny,没权限,得登陆 (后接-u <.username> -p)

1)myisamchk命令
与修复相关,其中isam是Indexed Sequence Access Method,因为基于索引,所以查找方便。
(仍然未知,先空着)
2)mysql 命令:
最有用的 应该是:

status  显示服务器状态信息
edit    打开默认编辑器(一般为vi),在里面编辑sql语句,wq后分号执行上述语句。
source  后接filename,执行filename里面的SQL语句。
tee     后接filename,将终端所有输出包括指令输出到filename中(这个是双向重定向,输出内容在filename,终端中都会出现)。

3)mysqladmin

create/drop <database>
status      与mysql命令的不同,此处显示的是整个mysql服务器的状态,比如queries per second
            (而mysql命令在mysql> 中是表示当前DB的状态, 在shell中表示的是一些Variables)
shutdown    停止服务器
ping        查看服务器是否关闭一般返回 mysqld is alive

4)mysqldump
这个指令是将数据库文件全部(包括数据)或部分以SQL命令集合的方式输出,指令如下:

mysqldump -u <username> -p <database name> > file.store
如 mysqldump -u root -p mysql > mysql.dump 

意外发现数据库“mysql”中有表’db‘, select全部一下,发现有我之前创立的数据库LETENO_DB,也就是说,所有数据库都将在mysql.db中保存,里面的字段包括Host, User,Db, 还有各种privilege。估计该表保存的是一个用户(User@Host)对于数据库(Db)的操作的权限(privilege)
下面是部分截图:
这里写图片描述
mysqldump命令还有一些选项:

-e  使用扩展的insert语法,能加快转储数据的加载速度 
-t  只转储表中的数据(DML?)
-d  只转储表的结构(DDL?)

注:
1)观摩了一下扩展的,应该是这么写的INSERT INTO student values (1,’ZHENG‘, 13), (2, ’LETENO‘,11),(3,’YOUNG‘,33);
2)发现他们添加数据(INSERT)的时候,先把表锁住 LOCK TABLES ’student‘ WRITE;在解锁UNLOCK TABLES;(此处估计应该写成UNLOCK TABLES ‘student’ 尝试了一下,不行,得只能用UNLOCK TABLES)
2.1)不过,尝试了一下lock之后在其他地方(另开终端)insert,无反应,直到我unlock之后才能添加进去。
2.2)尝试了unlock tables student read;发现“然并卵”,难不成select不属于表的读取(read)的范畴?那会是什么呢?
2.3)我又尝试在lock之后在另外一处也lock一下,发现无反应,也就是说这个是独占锁。
2.4)这个锁的粒度是进程,不是用户,当我另开终端,以同样的用户登入,发现还是操作不了,被锁上,等待解锁。

5)mysqlimport
与上面的指令是逆过程,参数是 文本文件 + 数据库名字
其实可以通过在mysql> 下:

mysql> create database NEW_DB
mysql> source mysql.dump.file

6) mysqlshow
一般需要用户登入(-u username -p),作用是:快速查看mysql的详细信息,如里面的数据库等等
直接上图:(我这里的用户proxy是咩有密码的)
mysqlshow -u proxy
mysqlshow -u proxy LETENO_DB
mysqlshow -u proxy LETENO_DB student
mysqlshow -u proxy LETENO_DB student sno

参数结果
无参列出所有可用的数据库
一个数据库为参数列出该数据库中的表
数据库和表名为参数列出表中的列
数据库、表和列为参数列出指定列的详细信息

其他命令:

1) grant 命令
详情看 编码 > 创建新用户

2)revoke 命令
revoke <privilege> on <tables> from <user>
REVOKE INSERT ON LETENO_DB.* FROM proxy;
注: revoke 只能撤回用户的权利,要完全删除用户,你得在mysql.user表中删除相应的用户记录。

mysql> DELETE FROM mysql.user WHERE user = "proxy"
mysql> FLUSH PRIVILEGES

单纯使用上面俩语句,是无法完全清除proxy用户的痕迹的。(当然,proxy无法再次登陆)但是对于数据库表的操作权限还没清除干净,可以通过select * from mysql.db where User="proxy"发现,仍然有proxy的痕迹,而且此时调用revoke撤proxy的权,发现报Error 1141:There is no such grant defined for user 'proxy' on host '%';估计是查找user表时发现查无此人(其实user表也是有权限priv字段的);所以说删除用户时要有一定顺序,先撤权,再删人。否则会删不干净的。
其实也未必,不能使用revoke,就使用最古老最简单的方法:delete
delete from mysql.db where user='proxy'
这样就删干净了。。。。

3)密码相关:
修改用户密码可以通过直接修改mysql.user中对应的字段达到目的,只不过一般密码都是加密过的,直接设置有些欠妥。所以mysql提供password(<password>)方法对密码加密,范例如下:

UPDATE mysql.user SET password=password("newpassword") WHERE user="proxy";

C语言访问MySQL数据库

1)编译

gcc -o a.out connect1.c -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient

2)编程
初始化:MYSQL* mysql_init(MYSQL *)
连接:MYSQL*

mysql_real_connect( MYSQL *connection, 
                    const char *server_host, 
                    const char *sql_user_name, 
                    const char *sql_password, 
                    const char *db_name, 
                    unsigned int port_number,
                    const char *unix_socket_name,
                    unsigned int flags);

关闭连接
mysql_close(MYSQL *connection);

例程:

#include <stdlib.h>
#include <stdio.h>

#include "mysql.h"

int main(int argc, char *argv[]) 
{
  MYSQL *conn_ptr;

  conn_ptr = mysql_init(NULL);
  if (!conn_ptr) 
  {
    fprintf(stderr, "mysql_init failed\n");
    return EXIT_FAILURE;
  }

  conn_ptr = mysql_real_connect(conn_ptr,
                                "localhost",
                                "proxy",
                                NULL,
                                "LETENO_DB",
                                0,
                                NULL,
                                0);

  if (conn_ptr)
  {
    printf("Connection success\n");
  } else 
  {
    printf("Connection failed\n");
  }

  mysql_close(conn_ptr);

  return EXIT_SUCCESS;  
}

错误处理:
unsigned int mysql_errno(MYSQL *connection)
char *mysql_error(MYSQL *connection)

执行mysql语句
int mysql_query(MYSQL *connection, const char *query)

受影响行数:
my_ulonglong mysql_affected_rows(MYSQL *connection)

获得resultset:
MYSQL_RES * mysql_store_result(MYSQL*);
一般用于mysql_query之后

取得resultset的一行结果,相当于resultset.next()
MYSQL_ROW mysql_fetch_row(MYSQL_RES)
其中MYSQL_ROW 是一个数组,数组的元素对应着查询的每个结果,也就是MYSQL_ROW[i] == mysqlrow.getString(i);
至于数组的大小:
int mysql_field_count(MYSQL*);

还能获得结果集的每个字段的属性:
MYSQL_FIELD * mysql_fetch_field(MYSQL_RES*)
其中 MYSQL_FIELD {
char *name;
char *table;
int type;
int length;
int flags; (列定义的标志,例如自增长AUTO_INCREMENT_FLAG 区分大小写BINARY_FLAG)
}
例子程序:

#include <stdlib.h>
#include <stdio.h>

#include "mysql.h"

MYSQL my_connection;
MYSQL_RES *res_ptr;
MYSQL_ROW sqlrow;

void display_header();
void display_row();


int main(int argc, char *argv[]) {
  int res;
  int first_row = 1;


  mysql_init(&my_connection);
  if (mysql_real_connect(&my_connection,
                         "localhost",
                         "proxy",
                         NULL,
                         "LETENO_DB",
                         0,
                         NULL,
                         0)) {

    printf("Connection success\n");

    res = mysql_query(&my_connection,
                      "SELECT sno, sname, age FROM student WHERE age>5");

    if (res) {
      printf("SELECT error: %s\n", mysql_error(&my_connection));
    } else {
      res_ptr = mysql_store_result (&my_connection);
      if (res_ptr) {

        while((sqlrow = mysql_fetch_row(res_ptr))) {
          if (first_row) {
            display_header();
            first_row = 0;
          }
          display_row();
        }
      }

      if (mysql_errno(&my_connection)) {
          fprintf(stderr, "Retrive error: %s\n", mysql_error(&my_connection));
      }
       mysql_free_result(res_ptr);
  }

    mysql_close(&my_connection);
} else {
      fprintf(stderr, "Connection failed\n");
      if (mysql_errno(&my_connection)) {
        fprintf(stderr, "Connection error %d: %s\n",
                mysql_errno(&my_connection), mysql_error(&my_connection));
      }
 }
    return EXIT_SUCCESS;
}


void display_header() {

  MYSQL_FIELD *field_ptr;

  printf("Column details:\n");
  while ((field_ptr = mysql_fetch_field(res_ptr)) != NULL) {
    printf("\t Name: %s\n", field_ptr->name);
    printf("\t Type: ");
    if (IS_NUM(field_ptr->type)) {
      printf("Numeric field\n");
    } else {
      switch(field_ptr->type) {
      case FIELD_TYPE_VAR_STRING:
        printf("VARCHAR\n");
      break;
      case FIELD_TYPE_LONG:
        printf("LONG\n");
      break;
      default:
        printf("Type is %d, check in mysql_com.h", field_ptr->type);
      }
    }

    printf("\t Max width %ld\n", field_ptr->length);
    if (field_ptr->flags & AUTO_INCREMENT_FLAG)
      printf("\t Auto increments\n");
    printf("\n");
  }
}



void display_row(){
  unsigned int field_count;

  field_count = 0;

  while (field_count < mysql_field_count(&my_connection)) {
    printf("%s ", sqlrow[field_count]);
    field_count ++;
  }
  printf("\n");
}

疑难杂症:

Table ‘LETENO_DB.STUDENT’ does not exist:

mysql的表都有“命名空间”,也就是数据库名。比如你这个表是放置在DB数据库下:
方法1) use DB
方法2) 使用里面的表(比如student)时, 写上全称DB.student

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值