MySQL5.0.15之create database

环境

  • windows10
  • wsl2
  • ubutun20.04
  • mysql5.0.15

数据目录

数据库目录和日志文件默认是/usr/local/var, 而在执行./configure时指定了安装目录/usr/local/mysql5.0.15, 则现在则为 /usr/local/mysql5.0.15/var

可以通过以下方式进行调整

  • 通过编译时指定
#通过--localstatedir进行指定,后续可以通过配置文件进行指定
$ ./configure --prefix=/usr/local/mysql5.0.15 \
--localstatedir=/usr/local/mysql5.0.15/data

原理

# configure文件
...
#未指定时的安装路径默认值
ac_default_prefix=/usr/local
...
prefix=NONE
#这里是单引号,并未计算值
localstatedir='${prefix}/var'
...
#解析命令行参数
for ac_option
do
    ...
     case $ac_option in
     ...
       #通过指定命令行指定,修改localstatedir的值
       -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
    localstatedir=$ac_optarg ;;
   ...
   esac
   ...
done
...
#检测是否赋值,未赋值则使用默认值
test "x$prefix" = xNONE && prefix=$ac_default_prefix

初始化脚本

#scripts/mysql_install_db.sh
...
ldata=
...
#从localstatedir中获取值
 test -z "$ldata" && ldata=@localstatedir@
...
#创建数据库目录
# Create database directories mysql & test
  if test ! -d $ldata; then mkdir $ldata; chmod 700 $ldata ; fi
  if test ! -d $ldata/mysql; then mkdir $ldata/mysql;  chmod 700 $ldata/mysql ; fi
  if test ! -d $ldata/test; then mkdir $ldata/test;  chmod 700 $ldata/test ; fi
  if test -w / -a ! -z "$user"; then
    chown $user $ldata $ldata/mysql $ldata/test;
  fi
...

#通过--datadir指定数据目录
mysqld_install_cmd_line="$mysqld $defaults $mysqld_opt --bootstrap \
--skip-grant-tables --basedir=$basedir --datadir=$ldata --skip-innodb \
--skip-bdb --skip-ndbcluster $args --max_allowed_packet=8M --net_buffer_length=16K"  
  • 通过my.cnf配置
[mysqld]
     # set datadir to the location of your data directory
     datadir=/usr/local/mysql/data
  • 启动时,命令行指定
mysqld --datadir=/usr/local/mysql/data

实践

语法

  CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] DB_NAME
         [CREATE_SPECIFICATION [, CREATE_SPECIFICATION] ...]

     CREATE_SPECIFICATION:
         [DEFAULT] CHARACTER SET CHARSET_NAME
       | [DEFAULT] COLLATE COLLATION_NAME

创建数据库

#mysql>为提示符
mysql> CREATE DATABASE mydb;
Query OK, 1 row affected (0.00 sec)

Linux下,数据库名区分大小写,Windows不区分大小写
关键字不区分大小写 (CREATE, DATABASE,USE,TABLE,ALTER,UPDATE,INSTER…)

数据库

一个数据库对应一个目录

$ cd /usr/local/mysql5.0.15/var
$ ls
DESKTOP-BQJUB01.err  DESKTOP-BQJUB01.pid  ib_logfile0 
 ib_logfile1  ibdata1  mysql  mysql-bin.000001 
  mysql-bin.000002  mysql-bin.000003  mysql-bin.index  test
# 当执行create database mydb后
# 其中多了一个mydb的目录
$ ls
DESKTOP-BQJUB01.err  DESKTOP-BQJUB01.pid  ib_logfile0 
 ib_logfile1  ibdata1  mydb  mysql  mysql-bin.000001 
  mysql-bin.000002  mysql-bin.000003  mysql-bin.index  test
字符集和排序规则

因在创建数据库时未指定字符集和排序规则,则默认使用实例的字符集和排序规则(编译指定)

#mydb目录中只有一个文件db.opt
$ cd mydb
$ ls
db.opt
#文件内容为数据库的字符集以及排序规则

$ cat db.opt
default-character-set=latin1
default-collation=latin1_swedish_ci

默认字符集处理流程

  • 可以通过 --with-charset进行默认字符集的设置
$ ./configure --help
  ...
  --with-charset=CHARSET
                          Default character set, use one of:
                          binary
                          armscii8 ascii big5 cp1250 cp1251 cp1256 cp1257
                          cp850 cp852 cp866 cp932 dec8 eucjpms euckr gb2312 gbk geostd8
                          greek hebrew hp8 keybcs2 koi8r koi8u
                          latin1 latin2 latin5 latin7 macce macroman
                          sjis swe7 tis620 ucs2 ujis utf8
  --with-collation=COLLATION
                     Default collation
  ...
  • 默认字符集为latin1,通过一系列的处理后,将写入到include/my_config.h中
# configure文件
DEFAULT_CHARSET=latin1
...


# Check whether --with-charset or --without-charset was given.
if test "${with_charset+set}" = set; then
  withval="$with_charset"
  default_charset="$withval"
else
  default_charset="$DEFAULT_CHARSET"
fi;


# Check whether --with-collation or --without-collation was given.
if test "${with_collation+set}" = set; then
  withval="$with_collation"
  default_collation="$withval"
else
  default_collation="default"
fi;

...
#将定义MYSQL_DEFAULT_CHARSET_NAME写入到confdefs.h文件中
cat >>confdefs.h <<_ACEOF
#define MYSQL_DEFAULT_CHARSET_NAME "$default_charset"
_ACEOF
...
  • 在client请求创建数据库时
    词法、语法、语义分析完后,识别为创建数据库命令,进行处理
//sql/sql_parse.cc
...
 case SQLCOM_CREATE_DB:
  {
    ...
    //lex->create_info从sql中获取,因未指定字符集等信息,所以为空
    res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias : lex->name),
			 &lex->create_info, 0);
    break;
  }
...

创建数据库(目录)

//libmysqld/sql_db.cc
mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
                     bool silent) {
  ...
  //实际上就是创建了一个目录
 if (my_mkdir(path,0777,MYF(0)) < 0)
  ...

  //写db.opt文件
  strmake(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
  if (write_db_opt(thd, path, create_info))
}

写数据库db.opt文件(字符集和排序规则)

static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
{
  register File file;
  char buf[256]; // Should be enough for one option
  bool error=1;

  if (!create->default_table_charset)
    create->default_table_charset= thd->variables.collation_server;

  ...
 
  //创建文件
  if ((file=my_create(path, CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0)
  {
    ulong length;
    //组装内容
    length= (ulong) (strxnmov(buf, sizeof(buf), "default-character-set=",
                              create->default_table_charset->csname,
                              "\ndefault-collation=",
                              create->default_table_charset->name,
                              "\n", NullS) - buf);

    /* Error is written by my_write */
    //写入内容
    if (!my_write(file,(byte*) buf, length, MYF(MY_NABP+MY_WME)))
      error=0;
    my_close(file,MYF(0));
  }
  return error;
}

从上面代码看,字符集等信息是从thd->variables.collation_server中获取的
而对象thd在创建的时候variables通过全局变量进行赋值

void THD::init(void)
{
  pthread_mutex_lock(&LOCK_global_system_variables);
  variables= global_system_variables;
  ...
  pthread_mutex_unlock(&LOCK_global_system_variables);
}

而global_system_variables在mysqld启动初始化阶段进程赋值
通过default_character_set_name获取字符集信息

// sql/mysqld.cc
static int init_common_variables(const char *conf_file_name, int argc,
				 char **argv, const char **groups)
{
  ...

  if (!(default_charset_info= get_charset_by_csname(default_character_set_name,
						    MY_CS_PRIMARY,
						    MYF(MY_WME))))
    return 1;
  
  ...

  /* Set collactions that depends on the default collation */
  global_system_variables.collation_server=	 default_charset_info;
  global_system_variables.collation_database=	 default_charset_info;
  global_system_variables.collation_connection=  default_charset_info;
  global_system_variables.character_set_results= default_charset_info;
  global_system_variables.character_set_client= default_charset_info;
  global_system_variables.collation_connection= default_charset_info;
  ...
}

而default_character_set_name的值先有一个默认值,这个默认值就是通过编译选项指定的

static void mysql_init_variables(void)
{
  ...
  default_character_set_name= (char*) MYSQL_DEFAULT_CHARSET_NAME;
  default_collation_name= (char*) MYSQL_DEFAULT_COLLATION_NAME;
  ...
}

后续在处理命令行或者配置文件时,将被–character-set-server重置

struct my_option my_long_options[] = {
...
 {"character-set-server", 'C', "Set the default character set.",
   (gptr*) &default_character_set_name, (gptr*) &default_character_set_name,
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
  ...
  //这个看描述被弃用了
   {"default-character-set", 'C', "Set the default character set (deprecated option, use --character-set-server instead).",
   (gptr*) &default_character_set_name, (gptr*) &default_character_set_name,
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
...
};

总结
默认的字符集和排序规则可以通过以下方式修改

  • 编译指定
  • 命令行指定
  • 配置文件指定
    优先级:编译 < 配置文件 < 命令行
    验证
  • 编译指定
$ CXXFLAGS="-std=gnu++98" ./configure --prefix=/usr/local/mysql5.0.15_utf8 \
--with-charset=utf8
... 

创建数据库后

# cat db.opt
default-character-set=utf8
default-collation=utf8_general_ci
  • 通过配置
    首先停止数据库
./bin/mysqladmin shutdown -uroot -p123456

修改配置文件

$ vi /etc/my.cnf
[mysqld]
...
character-set-server=ascii
...
$ ./bin/mysql -uroot -p123456 
mysql>create database mydb4;
Query OK, 1 row affected (0.00 sec)

编译为utf8,配置文件成功覆盖了默认值

$ cd var/mydb4
$ cat db.opt
default-character-set=ascii
default-collation=ascii_general_ci
  • 通过命令行
    启动时增加参数–default-character-set
$ ./bin/mysqld_safe --user=mysql --default-character-set=latin2 &
$ ./bin/mysql -uroot -p123456
mysql> create database mydb5;
Query OK, 1 row affected (0.01 sec)

编译为utf8,命令行成功覆盖

$ cd var/mydb5
$ cat db.opt
default-character-set=latin2
default-collation=latin2_general_ci
  • 命令行和配置文件同时存在
[mysqld]
character-set-server=ascii
./bin/mysqld_safe --user=mysql --default-character-set=latin2 &

进行登录创建数据库

$ ./bin/mysql -uroot -p123456
mysql> create database mydb6;
Query OK, 1 row affected (0.01 sec)

最终命令行的覆盖了配置文件中的

$ cd var/mydb6
$ cat db.opt
default-character-set=latin2
default-collation=latin2_general_ci
  • 会话级别的修改(只对当前会话生效)
    现在系统默认为utf8,通过会话变量修改
$ ./bin/mysql -uroot -p123456 
mysql>set character_set_server=latin1;
Query OK, 0 rows affected (0.06 sec)
mysql>create database mydb3;
Query OK, 1 row affected (0.00 sec)

成功覆盖字符集

$ cd var/mydb3
$ cat db.opt
default-character-set=latin1
default-collation=latin1_swedish_ci
  • 创建语句指定字符集
$ ./bin/mysql -uroot -p123456
mysql> create database mydb7 character set latin5;
Query OK, 1 row affected (0.03 sec)

指定字符集则使用指定的

$ cd var/mydb7
$ cat db.opt
default-character-set=latin5
default-collation=latin5_turkish_ci

选择数据库

  • 通过USE
mysql> USE 数据库名
  • 通过命令行
$ mysql -h HOST -u USER -p 数据库名
Enter password: ****

可以将密码直接写到-p后面p后面直接跟密码,不能有其它空格等, 不建议这样,密码直接被看到了,安全性低

$ mysql -h HOST -u USER -p密码 数据库名

删除数据库

mysql> drop database mydb2;
Query OK, 0 rows affected (0.07 sec)

总结

  • 一个数据库对应一个目录
  • 数据库目录中有一个db.opt文件记录数据库的字符集和排序规则
  • 数据库的字符集可以通过以下方式修改
    • 编译时指定默认值 --with-charset
    • 配置文件指定 character-set-server
    • 启动时命令行指定 --default-character-set
    • 创建数据库语句指定 character set
    • 会话级别,设置变量 set character_set_server
    • 通过alter database 数据库名 character set 字符集, 进行修改
  • 关键字不区分大小写
  • 数据库名称在类Unix系统下区分大小写,Windows不区分大小写
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值