文章目录

  • 一、数据库逻辑结构介绍
  • 二、数据库基本操作
  • 三、模式schema
    • 1.模式的定义
    • 2.模式的使用
    • 3.公共模式
    • 4.模式的搜索路径
    • 5模式的权限
    • 6.模式的移植性
  • 四、表
    • 1.创建表
    • 2.表的存储属性
    • 3.临时表
    • 4.默认值
    • 5.约束
    • 6.修改表
    • 7.表继承及分区表
    • 8.分区表
  • 五、触发器
    • 1.创建触发器
    • 2.语句级触发器与行级触发器
    • 3.BEFORE触发器与AFTER触发器
    • 4.删除触发器
    • 5.触发器的行为
    • 6.触发器函数中的特殊变量
  • 六、事件触发器
  • 七、表空间
    • 1.表空间的定义
    • 2.表空间的使用
  • 八、视图
    • 1.视图的定义
    • 2.创建视图
    • 3.可更新视图

一、数据库逻辑结构介绍

PG中, 数据的组织结构可以分为三层:

  • 数据库
    一个PG数据库服务下可以管理多个数据库,当应用连接到一个数据库时,只能访问这个数据库中的数据
  • 表、索引
    一个数据库中有很多表、索引。PG中称之为Relation,其他数据库叫Table
  • 数据行
    每张表中有很多行数据,PG中称之为Tuple,其他数据库叫Row

PG中,一个数据库服务(实例)下可以有很多数据库

  • 一个数据库不能属于多个实例
  • Oracle数据库中,一个实例只能有一个数据库,一个数据库可以在多个实例中

二、数据库基本操作

创建数据库
CREATE DATABASE testdb1 ENOCODING 'LATIN1' TEMPLATE template0;
ENOCODING 表示创建数据库使用的字符编码,一般不指定字符集,默认是UTF8
注意:template0公认不包含任何会受字符集编码或者排序影响的数据或缩影,可以作为创建任意字符集数据库的模板,默认就是template0;
若指定template1,要保证编码和区域设置要与template1模板数据库匹配;修改数据库
改变数据库的最大连接数
alter database mybase CONNECTION LIMIT 10;
改变数据库的名称
alter database mybase rename to mybase1;
改变数据库的配置参数,关闭数据库mybase上的默认索引扫描
alter database mybase set enable_indexscan to off;删除数据库
若有人连接到数据库上,则不能删除该数据库;
不能在事务块中删除数据库;
能在事务块中修改数据库;
drop database mybase;drop database if exists mybase;

三、模式schema

1.模式的定义

模式schema可以理解为一个命名空间或目录

  • 不同模式下可以拥有相同名称的表、函数等对象,且互相不冲突

  • PG中,不能同时访问不同数据库中的对象,当要访问另一个数据库中的表或者其他对象时,需要重新连接到新的数据库
    (1)一个用户连接到一个数据库后,可以同时访问这个数据库中多个模式的对象。
    PG中模式的概念与Mysql中Database的概念是等同的,在Mysql中可以同时访问多个Database中的对象,与在PostgreSQL中可以同时多个Schema中的UI小是一样的;
    Oracle数据库中的一个用户就对应一个schema。
    (2)PG中,一个数据库包含一个或者多个模式,模式中又包含表、函数、操作符等函数对象

  • 不同模式下可以有相同名称的表、函数等对象且相互不冲突

  • PG使用模式的原因
    (1)允许多个用户在使用同一个数据库时彼此不干扰
    (2)数据库对象放在不同的模式下,然后组织成逻辑组,让他们更便于管理
    (3)第三方的应用可以放在不同的模式中,这样就不会和其他对象的名字冲突了

2.模式的使用

CREATE SCHEMA mydba;查看有哪些模式
\dn
DROP SCHEMA mydba;创建一个模式的同时,创建表的视图
CREATE SCHEMA mysba
CREATE TABLE t1 (id int, title text)
CREATE TABLE t1 (id int, contend text)
CREATE VIEW v1 AS SELECT a,id,a.title,b.contend from t1 a, t2 b where a.id=b.id;在模式中修改名称和属主
改名称:
alter schema mydba rename to mydba2;改属主:
alter schema mydba owner to mydba3;

3.公共模式

默认创建的数据库访问的都是public模式。

  • 模式访问方式:要创建或者访问模式中的对象,需要先写出模式的名字
schema_name.table_name

4.模式的搜索路径

类似LInux中的$PATH

  • 显示当前搜索路径
SHOW search_path;

5模式的权限

默认情况下,用户无法访问模式中不属于他们的对象。

  • 若要访问,模式的所有者必须在模式上赋予他们USAGE权限
其他用户不能在模式public下创建对象
REVOKE CREATE on SCHEMA public FROM PUBLIC;
第一个public是模式的名称(标识符),第二个PUBLIC是所有用户(关键字,关键字有大写或者小写)以wangji用户连接osba数据库
\c osba wangji;create table t1(id int);失败

6.模式的移植性

  • 与Oracle数据库兼容:
    (1)Oracle中,模式和用户的概念一样。
    移植到PG时,PG为每个用户都创建一个与用户名同名的模式,那么就能与Oracle数据库兼容;
    (2)删除public模式;

  • 与Mysql兼容:
    若Mysql实例中有三个数据库,移植到PG时,应该创建三个模式。

四、表

1.创建表

主键只有一个
create table test01(id int primary ket, node varchar(20));复合主键
create table test01(id1 int, id2 int,node varchar(20), CONSTRAINT pk_test01 primary key(id1,id2));唯一键
create table test03(id1 int, id2 int,node varchar(20), CONSTRAINT pk_test03 primary key(id1,id2), CONSTRAINT uk_test03_id3 UNIQUE(id3));CHECK
CREATE TABLE chile(name varchar(20), age int, note text, CONSTRAINT ck_chile_age CHECK(age<19));用其他表为模板创建新表
CREATE TABLE baby (LIKE chile);用其他表为模板创建新表,且把所有属性都复制过来
CREATE TABLE baby2 (LIKE chile INCLUDING ALL);

2.表的存储属性

TOAST(“The Oversized-Attribute Storage Technique”)

  • 用于存储一个大字段的值,由于PG页面大小固定为8KB且不允许跨越多个页面,所以大字段值通常被压缩或切片成多个物理行存到另一张系统TOAST表中
  • 支持TOAST的数据类型必须是变长的
将表的content字符安的TOAST字段修改为EXTERNAL
CREATE TABLE blog(id int, title text, content text);
ALTER TABLE blog ALTER content content SET STORAGE EXTERNAL;

fillfactor填充因子

  • eg:设置为60,则表示往一个数据库中插入的数据占用60%的空间后,就不再往这个数据库中插入数据了,剩余的40%的空间是为了更新数据使用的。
  • toast.fillfactor是这个表中TOAST表的填充因子

3.临时表

不管是事务级的临时表还是会话级的临时表,当会话结束时,临时表就会消失。
会话级的临时表

  • 数据可以一直保存在整个会话的生命周期内

事务级的临时表

  • 数据只存在于这个事务的生命周期内
创建一个同名的临时表(默认是会话级)
create TEMPORARY table tmp_t1(id in primary key, note text);
等价于
create TEMP table tmp_t1(id in primary key, note text);
\d
insert into tmp_t1 values(1,'111');开启另一个会话
psql postgres
\d pg_temp_2.tmp_t1
select * from pg_temp_2.tmp_t1;不能访问创建一个事务级别的临时表
on commit delete rows表示数据只存在于事务周期中,事务一提交,数据就消失
create TEMPORARY table tmp_t2(id in primary key, note text) on commit delete rows;
begin;
insert into tmp_t2 values(1,'aaa');
select * from tmo_t2;
end;
select * from tmo_t2;

4.默认值

create table student (no int, name varchar(20), age int default 15);
insert into student (no,name) values(1,'张三');
update student set age=default where id=2;默认值在插入的时候计算
create table blog(id int ,title text, created_date_timestamp timestamp default now());

5.约束

SQL允许在字段和表上定义约束,约束允许你对数据进行任意控制

(1)检查约束
create table persons(name varchar(40);age int CHECK(age>=40 and age<=150),sex boolean
);
给约束取名字
create table persons(name varchar(40);age int CONSTRAINT check_age CHECK(age>=40 and age<=150),sex boolean
);CREATE TABLE books(book_no integer,name text,price numeric CHECK(price>0),字段约束disconted_price numberric CHECK(disconted_price>0),CHECK(price > disconted_price )表约束
);
等价于
CREATE TABLE books(book_no integer,name text,price numeric,disconted_price numberric,CHECK(price>0)CHECK(disconted_price>0),CHECK(price > disconted_price )
);(2)非空约束
一个非空约束总是被写成一个字段约束。
一个字段约束可以有多个约束。
CREATE TABLE books(book_no integer not null,name text,price numeric
);
多个约束写法
CREATE TABLE books(book_no integer not null,name text,price numeric NOT NULL CHECK(price > 0)
);(3)唯一约束
字段约束
CREATE TABLE books(book_no integer UNIQUE,name text,pricee numeric
);表约束
CREATE TABLE books(book_no integer,name text,pricee numeric,UNIQUE(book_no )
);(4)外键约束(表之间的参照完整性约束)
create table class(class_no int primary key,class_name varchar(40)
);外键约束REFERENCES class(class_no)表面在学生表中class_no的取值必须出现在表class中,且为class_no中的一个数值
create table student(student_no int primary key,student_name varchar(40),age int,class_no int REFERENCES class(class_no)
);

6.修改表

(1)增加字段
alter table class add column class_teacher varchar(40);
alter table class add column class_teacher varchar(40) CHECK(class_teacher <> '');(2)删除字段
alter table class drop COLUMN class_teacher;
删除外键依赖
alter table class drop column class_no CASCADE;(3)增加约束
alter table student ADD CHECK(age<16);
alter table class add constraint unique_class_teacher UNIQUE(class_teacher);增加非空约束
alter table student alter column student_name set not null;(4)删除约束
\d student;查出约束
删除有名字的约束
alter table student drop constraint student_age_check;删除非空约束
alter table student alter column student_name drp not null;(5)修改默认值
不会改变现有的任何数据将,仅改变未来insert的
alter table student alter column age set DEFAULT 15;(6)删除默认值
alter table student alter column age drop DEFAULT;(7)修改字段数据类型
只有在字段里现有的每个项都可以隐式地转换成新类型时,才可以
alter table student alter column student_name TYPE text;(8)重命名字段
alter table books rename column book_no to book_id;(9)重命名表
alter table class rename to classs;

7.表继承及分区表

PG特有

  • (1)所有父表的检查约束和非空约束都会自动被所有子表继承
  • (2)一个子表可以从多个父表继承,他将拥有所有父表字段的总和
  • (3)select,update,delete,alter table等命令访问父表时,也会同时访问或操作相应的子表。除非使用reindex,vacuum
  • (4)唯一约束、外键的作用域不会扩大到子表
create table persons(name text,sex boolean,age int
);
增加一个学生表students,比persons表多了一个班级号class_no
class table students(class_no int
)INHERITS(persons);只显示父表的结果,不显示子表的
select * from only persons;

8.分区表

表分区就是把逻辑上的一个大表分割成物理上的几个小块。

  • 多大的数据使用分区表?表的大小超过了数据库服务器的物理内存大小则使用
  • 使用继承实现的分区表时,一般会让父表为空,数据都存储在子表中
  • 分区的优化技巧:打开约束排除constraint_exclusion是一种查询优化技巧,constraint_exclusion默认就是partition,若采用默认值,则在SQL查询中将WHERE语句的过滤条件与表上的CHECK条件进行对比,就可以得知不需要扫描分区,从而跳过相应的分区表,所以性能就得到了提升。
>set constraint_exclusion='on';

五、触发器

触发器trigger是一种由事件自动触发执行的特殊的存储过程

  • 事件可以是对一个表进行INSERT、UPDATE、DELETE等操作
  • 触发器经常用于加强数据的完整性约束和业务规则上的约束等

1.创建触发器

要求:如果想在删除学生表中的一条记录时,就把这个学生在成绩表score中的成绩记录也删除掉

学生表
CREATE TABLE student(student_no int primary key,student_name varchar(40),age int
);考试成绩表
CREATE TABLE score(student_no int,chinese_score int,math_score int,test_date date
);先创建触发器的执行函数,返回来为触发器类型
CREATE OR REPLACE FUNCTION student_delete_trigger()
RETURNS TRIGGER AS $$
BEGINDELETE FROM score WHERE student_no =OLD.student_no RETURN OLD;
END;
$$
LANGUAGE plpgsql;再创建触发器
CREATE TRIGGER student_delete_triggerAFTER DELETE ON studentFOR EACH ROW EXECUTE PROCEDURE student_delete_trigger();INSERT into student values();
INSERT into score values();
DELETE FROM student where student_no=3;
select * from score;

2.语句级触发器与行级触发器

语句级触发器

  • 执行每个SQL时,只执行一次

行级触发器

  • 每行触发一次
为student创建一张log表
CREATE TABLE log_student(update_time timestamp,db_user varchar(40),操作的数据库用户名opr_type varchar(6),操作类型:insert、delete、update
)创建记录log的触发器函数
CREATE FUNCTION log_student_trigger ()
RETURNS trigger AS
$$
BEGINTG_OP是触发器的特殊变量:DML操作类型INSERT INTO log_student values(now(), user, TG_OP)RETURN NULL;
END;
$$
LANGUAGE "plpgsql";(1)语句级触发器
CREATE TRIGGER log_student_triggerAFTER INSERT OR DELETE OR UPDATE on student FORSTATEMENT EXECUTE PROCEDURE log_student_trigger();INSERT INTO student  values();
select * from log_student;
删除log_student中的记录
delete from log_student;(2)行级触发器
删除触发器前需要清除log_student中的记录
drop trigger log_student_trigger on student;
delete from log_student;
建一个行级触发器
CREATE TRIGGER log_student_trigger2AFTER INSERT OR DELETE OR UPDATE on student FOR RAW EXECUTE PROCEDURE log_student_trigger ()

3.BEFORE触发器与AFTER触发器

语句级别的before触发器是在语句开始做任何事情之前就被触发了的,而语句级别的after触发器是在语句结束时才触发的;

行级别的before触发器在对特定航进行操作之前触发,行级别的after触发器是在语句结束时才触发的,但是它会在任何语句级别的after触发器被触发之前触发

  • 方法中NEW和OLD指的是触发器监听的某表某行的新数据和未更新前的数据
BEFORE触发器可以直接修改NEW值,可以改变实际的更新值触发器函数:在插入表或者更新表时,在student_name后加上student_no学号
CREATE FUNCTION student_use_new_name_trigger()
RETURNS trigger AS '
BEGINNEW.student_name=NEW.student_name||student_no;RETURN NEW;
END;'
LANGUAGE "plpgsql"before触发器是在更新数据之前就触发的
CREATE TRIGGER user_new_student_triggerBEFORE INSERT OR UPDATE on studentFOR EACH RAW EXECUTE PROCEDURE student_use_new_name_trigger ();

4.删除触发器

删除触发器时,触发器函数不会被删除;

当删除表时,表上的触发器也会被删除;

DROP TRIGGER user_new_student_trigger on student;

5.触发器的行为

触发器函数的返回值RETURN总是NULL,必须显式写上

  • BEFORE和INSTEAD OF行级触发器,返回的是NULL,则表示忽略对当前行的操作;
    返回非NULL,返回的行将成为新插入的行或者将要更新的行;
  • AFTER的行级触发器,返回值会被忽略
  • 如果是同一事件上的的多个触发器,就按照触发器的名字顺序来触发。
    (1)BEFORE和INSTEAD OF行级触发器,每个触发器返回的行将成为下一个触发器的输入
    (2)BEFORE和INSTEAD OF行级触发器返回的内容为空, 则修改行上的其他行级触发器也不会触发

6.触发器函数中的特殊变量

对于pl/pgSQL触发器函数来说,系统在调用它的时候,会开声明段里自动创建几个特殊的变量:

NEW:数据类型是record。在insert、update操作触发时存储新的数据行。

OLD:数据类型是record。在update、delete操作触发时存储旧的数据行。

TG_NAME:数据类型是name。触发器名称。

TG_WHEN:内容为"BEFORE"或“AFTER”,可以用来判断是BEFORE触发器还是AFTER触发器。

TG_LEVEL:内容为“ROW”或“STATEMENT”,可以用来判断是语句级触发器还是行级触发器。

TG_OP:内容为“INSERT”、“UPDATE”、“DELETE”、“TRUNCATE”,用于指定DML语句类型。

TG_RELID:触发器所在表的 oid。

TG_TABLE_NAME:触发器所在表的表名称。

TG_SCHEMA_NAME:触发器所在表的模式。

TG_NARGS:在创建触发器语句中赋予触发器过程的参数个数。

TG_ARGV[]:text类型的一个数组。创建触发器语句中指定的参数。

六、事件触发器

目的是解决版本不支持DDL触发器的功能,事件触发器支持以下三种DDL事件

  • ddl_command_start:一个DDL开始执行前被触发
  • ddl_command_end:一个DDL执行完成后被触发
  • sql_drop:删除一个数据库对象前被触发

事件触发器函数仅支持TG_EVENT和TG_TAG 变量

  • TG_EVENT:ddl_command_start,ddl_command_end,sql_drop
  • TG_TAG :具体的哪种DDL操作,eg:CREATE TABLE,DROP TABLE。但是TRUNCATE table test01;还是可以用的
禁止所有DDL语句
CREATE OR REPLACE FUNCTION abort_any_command()
RETURN event_trigger
LANGUAGE plpgsql AS $$
BEGINRAISE EXCEPTION 'command % is disables', tg_tag;
END;
$$CREATE EVENT TRIGGER abort_DDL ON DDL_command_startEXECUTE PROCEDURE abort_any_command();禁止事件触发器
ALTER EVENT TRIGGER abort_DDL DISBLE;

事件触发器sql_drop

  • 可以调用一个函数pg_event_trigger_dropped_objects()获取删除数据库对象的信息
查询系统视图pg_event_trigger看到已有的事件触发器
select * from pg_event_trigger;创建一个事件触发器,记录数据库中对象删除的审计日志
--创建审计记录表
create table log_drop_objects(
op_time         timestamp, --操作执行时间
ddl_tag         text,  --执行的ddl操作
classid         Oid,
objid           Oid,
objsubid        OID,
object_type     text,
schema_name     text,
object_name     text,
object_identify text
);--创建触发器函数
create function event_trigger_log_drops()
returns event_trigger language plpgsql as $$
declare
obj record;
begin
insert into log_drop_objects select now(),tg_tag,classid,objid,objsubid,
object_type,schema_name,object_name,
object_identity from pg_event_trigger_dropped_objects();
end
$$;--创建触发器
create event trigger event_trigger_log_drops
on sql_drop
execute procedure event_trigger_log_drops();create table test01(id int primary key, note varchar(20));
alter table test01 drop column note;
drop table test01;
删除一张表,数据库实际还删除了表的主键约束,主键索引,以及和以表名相同的类型等内容
select ddl_tag,object_type,object_name,object_identity from log_drop_objects;

修改事件触发器

ALTER EVENT TRIGGER name DISABLE
ALTER EVENT TRIGGER name ENABLE [ REPLICA | ALWAYS ]
ALTER EVENT TRIGGER name OWNER TO new_owner
ALTER EVENT TRIGGER name RENAME TO new_name

七、表空间

1.表空间的定义

PG中,表空间实际上是为表指定一个存储的目录

2.表空间的使用

创建表空间:create tablespace tbs_data location '/home/pgdata'创建数据库时指定默认的表空间:create database db01  tablespace tbs_data;改变一个数据库的默认表空间时的语法:alter database db01 set tablespace tbs_data;创建表的时候也可以指定表空间:create table test01(id int, note text) tablespace tbs_data;创建索引的时候同样可以指定表空间:create index idx_test01_id on test01(id) tablespace tbs_dasta;建唯一约束时,也可以指定约束索引的表空间:alter table test01 add constraint unique_test01_id unique(id) using index tablespace tbs_data;增加主键时,也可指定主键索引的表空间:alter table test01 add constraint pk_test01_id primary key(id) using index tablespace tbs_data;把表从一个表空间移动到另一个表空间的命令:alter table test01 set tablespace pg_default;
注意:在移动表的时候会锁表,此时对该表的所有操作都将被阻塞,
包括select操作,所以请考虑在合适的实际做这个操作。

八、视图

1.视图的定义

视图是查询语句定义额虚拟表

  • 从视图重看大ode数据可能来自数据库中的一张或者多张表
  • 一般数据库提供的视图大多数是只读的

2.创建视图

创建一个可以隐藏password的视图:

postgres=# create table users(
id int,
user_name varchar(40),
password varchar(256),
user_email text,
user_mark text
);create view vw_users as select id,
user_name,user_email,user_mark from users;使用temp 或者 temporary 关键字来创建视图,当session结束时,视图消失
postgres=# create temp view vw_users as select id,user_name,user_email,user_mark from users;若session未结束,\d可以看到临时临时视图视图也能为查询的各列定义另一个名称。列如将原来表中的id、user_name、user_email、user_mark等
列名重新定义为no、name、email、mark
postgres=# create view vm_users(no,name,email,mark) as select id,user_name,
postgres-# user_email,user_mark from users;

3.可更新视图

若直接update视图中的字段失败,则可以使用规则来update视图

postgres=# create table users(
id int,
user_name varchar(40),
password varchar(256),
user_email text,
user_mark text
);create view vw_users as select id,
user_name,user_email,user_mark from users;create rule vw_users_upd as on update to vw_users do instead update users set user_email=NEW.user_email;update vw_users set user_email='zhangsan@163.com' where id=1;

增加一个删除规则的方式来实现删除视图中的数据

CREATE RULE vm_users_del AS ON DELETE TO vw_users DO INSTAED DELETE FROM users WHERE od=OLD,id;delete from vw_users where id=1;

增加一个插入规则来实现可插入数据的视图

CREATE RULE vm_users_del AS ON INSERT TO vw_users DO INSTEAD INSERT INTO users(id, user_name,password, user_email,user_mark) values(NEW.id, NEW.user_name, '111', NEW.user_email, NEW.user_mark);insert into vw_users values(2,'王继','jiwangreal@163.com','hello world')

通过INSTAED OF触发器更新视图

CREATE OR REPLACE FUNCTION vw_users_insert_trigger()
RETURNS TRIGGER AS $$
BEGININSERT INTO users values(NEW.id, NEW.user_name, '111', NEW.user_email, NEW.user_mark);RETURN NULL;
END;
$$
LANGUAGE plpgsql;CREATE OR REPLACE FUNCTION vw_users_update_trigger()
RETURNS TRIGGER AS $$
BEGINUPDATE FROM users SET user_email=NEW.user_email() WHERE id=NEW.id;RETURN NULL;
END;
$$
LANGUAGE plpgsql;CREATE OR REPLACE FUNCTION vw_users_delete_trigger()
RETURNS TRIGGER AS $$
BEGINDELETE FROM users WHERE id=NEW.id;RETURN NULL;
END;
$$
LANGUAGE plpgsql;CREATE TRIGGER insert_vw_users_triggerINSERT OF INSERT ON vw_usersFOR EACH ROW EXECUTE PROCEDURE vw_users_insert_trigger();CREATE TRIGGER update_vw_users_triggerINSERT OF INSERT ON vw_usersFOR EACH ROW EXECUTE PROCEDURE vw_users_update_trigger();CREATE TRIGGER delete_vw_users_triggerINSERT OF INSERT ON vw_usersFOR EACH ROW EXECUTE PROCEDURE vw_users_delete_trigger();

<POSTGRESQL修炼之道:从小工到专家>之逻辑结构管理(1-5节)相关推荐

  1. 《PostgreSQL修炼之道-从小工到专家》读书笔记

    PostgreSQL数据库 索引 事务特性 事务隔离级别: 三种问题 四种隔离级别 PostgreSQL中的事务隔离 多版本并发控制(MVCC) MVCC用到的系统字段 事务状态 PostgreSQL ...

  2. 读《程序员修炼之道——从小工到专家》(The Pragmatic Programmer: From Journeyman to Master)

    花了几天时间略读完了<程序员修炼之道--从小工到专家>(The Pragmatic Programmer: From Journeyman to Master).总体感觉就像是一位多年开发 ...

  3. [拇指飞动]读《程序员修炼之道:从小工到专家》

    在很多Must Read推荐书目中,<The.Pragmatic.Programmer_From.Journeyman.to.Master[1999][CHS][PDF]>(<程序员 ...

  4. 《程序员的修炼之道——从小工到专家》读书笔记

    概览 最近读了<程序员的修炼之道--从小工到专家>这本书,感觉这本书又是属于开发进阶的必读的一本著作,而且我觉得一遍甚至还只是入门,这是一本值得都第二遍的书.再次推荐给大家,没看过的都去看 ...

  5. 程序员修炼之道-从小工到专家读后感

    最近3周,利用早上的时间,阅读了<程序员修炼之道-从小工到专家>,这本书写得非常好,深有感触.可能由于水平有限,对于其中一些珠玑理解没有那么强的感受.这里主要讲一些我感触特别深的点. 一. ...

  6. 程序员修炼之道–从小工到专家

    <程序员修炼之道–从小工到专家> <程序员修炼之道–从小工到专家>[美]Andrew Hunt / David Thomas 著 马维达 译   图片来源-百度图片 看这本书主 ...

  7. 《程序员修炼之道–从小工到专家》读书笔记

    <程序员修炼之道–从小工到专家>的读书笔记 <程序员修炼之道–从小工到专家>[美]Andrew Hunt / David Thomas 著 马维达 译 看这本书主要使用了检视阅 ...

  8. 读书笔记2014第4本:程序员修炼之道-从小工到专家(第一章)

    <程序员修炼之道-从小工到专家>是一本1999年写的老书,但15年之后,书中的许多道理依然没变,时不时拿出一章咀嚼一下仍有许多可回味之处. 第一章 注重实效的哲学 1.我的源码让猫给吃了 ...

  9. 程序员修炼之道--从小工到专家(一)

    这个假期里看了一下这本书,乍一看名字,觉得这就是比较鸡汤类的书吧,但是在看了一部分之后,忽然感觉到,以前的自己真的是很无知,一直就没有认识到做一个真实的项目的困难性,也根本就没有真正的认识到怎么去做一 ...

  10. 程序员基本功书籍--程序员修炼之道——从小工到专家

最新文章

  1. 来呀!AI喊你斗地主——首个搞定斗地主的深度神经网络
  2. 智源研究院首席科学家刘嘉:认知神经的未来发展规划是什么?
  3. GDB下查看内存命令(x命令)
  4. 二维码的生成(可设置大小)以及插件下载地址
  5. java jdk 64 1.8_JDK1.8 64位官方下载
  6. 内插函数恢复模拟信号
  7. MATLAB app designer中全局变量的使用
  8. 阿里云主机(ECS)入门(图文说明)详细了解
  9. 创龙Xilinx Zynq-7000系列SoC高性能处理器开发板的SFP+接口、FMC接口
  10. 人工智能“六步走”学习路线
  11. python中面向对象的缺点_python中的面向对象和面向过程
  12. 基于Qt的房贷计算器
  13. 飞思卡尔MC9S12系列单片机地址影射以及分页问题
  14. 输出一个贷款的迁徙率计算的代码
  15. 海康EHOME5.0协议无法成功注册EasyCVR平台的原因排查
  16. 使用阿里云消息服务mns发送短信
  17. Python学习 matplotlib库 霍兰德人格分析雷达图
  18. Online PDF to PNG, PDF to JPEG, PDF to WEBP, PDF to TXT - toolfk程序员在线工具网
  19. 8、ZigBee 开发教程之基础篇—CC2530 定时器T3的使用
  20. 网页制作初级教程学习资料

热门文章

  1. 【工作小技巧】cmd 批量移动文件
  2. pc模式 华为mate30_很实用!华为Mate?30全系支持PC模式,无线充+投屏更方便!
  3. python篇 006-- pycharm vsc 编写python(对比浅析混合使用) pycharm篇
  4. mysql 免费报表工具_10款最出色的免费数据库管理工具
  5. 通俗易懂讲解数据库三大范式
  6. UWP VS创建UWP应用项目
  7. jetlinks之Thing(六)
  8. alios thing - rhino内核 - 内存管理
  9. java中操作docker
  10. 【洛谷题解】P1042 [NOIP2003 普及组] 乒乓球