Git之旅 - 代码仓库与数据库

在计算机中凡是需要复用以及重要的数据,都会落到磁盘。秉承从Unix开始到现在常用的操作系统设计哲学:一切皆文件。那么常见的数据存储是如何组织的呢,这里通过MySQL与Git简单的对比来进行揭秘(不涉及太深层次),下面以一个简单实现为例来说明。

1. MySQL与数据存储

想要查找MySQL的数据存在哪里,首先需要找到数据的存储位置。

I.找到MySQL的配置文件
一般位于/etc/my.cnf

II.找到关于存储路径的配置(每个人的路径可能不一样)
innodb_data_home_dir = /usr/local/mariadb/var

II.查看数据的构成(这里以:ishanghai这个库为例)
通过命令行查询MySQL下面所有存在的数据库以及ishanghai数据库的表。

通过查看数据存储路径下面的目录结构来查看其构成。

结论:
每一个数据库在数据存储上对应一个文件夹, 每一个表也有对应文件 数据以文件形式存在 (经过数据压缩以及其他处理,不能直接查看) ish_comments.frm 与 ish_comments.idb 组成一个ish_comments表(不同存储引擎,文件个数不同)

创建新的数据库以及表(可以自己执行,并观察现象)

1
2
3
4
5
6
7
8
9
10
11
12
> mysql -uroot -p
> show databases;
> create database test;
> show database;

> // 观察有新文件夹test生成
~ tree /usr/local/mariadb/var

> create table t1 (id int auto_increment primary key, name varchar(10) not null)engine=innodb charset=utf8;

> // 观察test下面有新文件生成
~ tree /usr/local/mariadb/var

2. 神秘的.git文件夹

.git文件夹位置项目代码根目录下面,在类UniX系统中以.(点)开头的文件夹或者文件是被隐藏起来的。

I. 生成.git文件夹(生成一个名字为test的代码仓库)

1
~ git init test

提示:Initialized empty Git repository in /Users/ivans/myCode/test/.git/

II. 查看.git目录

1
~ tree .git

对应的常用文件以及目录作用描述:

3. 内容寻址文件系统

Git是一个内容寻址文件系统。听起来很酷,但这是什么意思呢?

你可以向该数据库插入任意类型的内容,它会返回一个键值,通过该键值可以在任意时刻再次检索(retrieve)该内容。类似于mysql的insert操作,insert一条数据会返回一个主键。可以通过该主键获取insert的数据信息。

-w 选项指示 hash-object 命令存储数据对象。若不指定此选项,则该命令仅返回对应的键值
--stdin 选项则指示该命令从标准输入读取内容

1
echo "hello git,i'm coming ... " | git hash-object -w --stdin

// 通过该语句,向git存储了一条信息(相当于向MySQL中插入了一条数据)。git返回一个字符串(可以想成MySQL的主键),同时git把生成的信息存储在了 文件 .git/objects/c9/cc4892d84b76fbc475dfe8b67f12dd571b3b93

1
git cat-file -p 25fef7f16d9817e154c73ad2009c74eafd7277c3

// 通过该语句,从git中获取到了我存储起来的数据。(相当于从MySQL通过主键查询一条数据)

到这里,你还想说,git不是数据库或者不像数据库吗?

是不是很cool!

4. 一次完整的git提交

看完上面的操作,感觉是有点风骚。但是,没人会那么用。那么下面就来一次完整的git提交,并观察其仓库变化吧。

注意观察:在我commit之后,提示里面有一个字符串:5c9bbc9

再次观察代码仓库的变化:

这次多了好几个文件呢。

看到没,5c9bbc9就是其中一个文件的开头几个字母。

敢肯定的是:内容绝对存储在某一个文件中。

还记得在Git之旅—子命令与设计哲学介绍过:剖析git的3把刷子与1枚瑞士军刀吗,这里就用到了它们。

仔细对比各个文件的关系,不难发现

1
0645b5ebc49c64b3505654428d691ba558235ff7

保存文件内容

1
cef73df56546dfc5d950faba13d55e801b4907ba

类型是blob,指向文件内容的标识字符串

1
5c9bbc98d896c54142a8326ca1571cb15f65825d

包含cef73df56546dfc5d950faba13d55e801b4907ba,并且内容与 git log显示的几乎一样。

多出来的另外两个文件中存储的信息。

明显预知到,每次提交是不是至少会多出来3个文件(就像MySQL中每次创建表都会多出几个文件)。