瀏覽代碼

Gitbook Auto Published

Willin Wang 8 年之前
父節點
當前提交
a11dbef5e5
共有 6 個文件被更改,包括 235 次插入2 次删除
  1. 7 2
      SUMMARY.md
  2. 80 0
      project/db/mysql.md
  3. 5 0
      project/db/redis.md
  4. 0 0
      project/js/benchmark.md
  5. 57 0
      project/js/es6.md
  6. 86 0
      project/test.md

+ 7 - 2
SUMMARY.md

@@ -7,8 +7,13 @@
   - [系统实践](design/system.md)
 - [项目](project/README.md)
   - [结构](project/structure.md)
-  - [Benchmark](project/benchmark.md)
-  - [Test](project/test.md)
+  - JavaScript
+    - [ES6/7](project/js/es6.md)
+    - [Benchmark](project/js/benchmark.md)
+    - [Test](project/js/test.md)
+  - DB
+    - [MySQL](project/db/mysql.md)
+    - [Redis](project/db/redis.md)
 - [运维](operation/README.md)
   - [CI工作流](operation/workflow.md)
   - [重启服务](operation/restarter.md)

+ 80 - 0
project/db/mysql.md

@@ -0,0 +1,80 @@
+# MySQL
+
+## 查询优化
+
+### LIMIT 1
+
+单条数据查询
+
+```sql
+SELECT uid FROM ?? WHERE email = ? LIMIT 1
+```
+
+或单条记录更改
+
+```sql
+UPDATE ?? SET lastonline = if(updatedat < ? , ? , lastonline), ? WHERE did =  ? LIMIT 1
+```
+
+或单条记录删除,加 `LIMIT 1`。
+
+## SELECT 嵌套 SELECT
+
+如:
+
+```sql
+SELECT did,type,
+  (select username from ?? as t1 where t1.uid = fromuid LIMIT 1) username,
+  (select email from  ?? as t1 where t1.uid = fromuid LIMIT 1) email,
+FROM ?? WHERE --xxx
+```
+
+优化为:
+
+```sql
+SELECT t1.`type`,t1.did,t2.username,t2.email FROM ??
+  LEFT JOIN ?? ON t1.touid=t2.uid
+WHERE --xxx
+```
+
+
+## 多次JOIN
+
+```sql
+SELECT
+   `t1`.`xxx`,
+   `t1`.`xxx`,
+   `t2`.`xxx`,
+   `t2`.`xxx`,
+   `t3`.`xxxx`,
+   `t3`.`xxx`,
+   `t4`.`xxx`,
+   `t5`.`xxxx`
+FROM (((?? `t1`
+  left join ?? `t2` on((`t1`.`did` = `t2`.`did`)))
+  left join ?? `t3` on((`t1`.`did` = `t3`.`did`)))
+  left join ?? `t4` on((`t4`.`username` = `t1`.`did`)))
+  left join ?? `t5` on((`t1`.`did` = `t5`.`did`)))
+WHERE --xxx;
+```
+
+80条记录结果的查询约40s,拆分查询,t1-t3主要查询,t4、t5表的数据只在部分记录中需要,分别做两次查询,共计三次查询,优化后查询总耗时1s以内。
+
+## 表结构优化
+
+### 引擎
+
+如果需要用事务用 `InnoDB`。
+
+如果对查询效率要求高用`MyISAM`。
+
+### 表结构优化
+
+基于 `MyISAM` 引擎。
+
+* 避免使用自增ID;
+* 避免使用`varchar`,而用`char`;
+* 避免使用`text`,而用`blob`;
+* 避免使用`外键`;
+* 不允许空 `null`;
+* 如果查询的WHERE条件有多个字段,应该创建`联合索引`。

+ 5 - 0
project/db/redis.md

@@ -0,0 +1,5 @@
+# Redis
+
+## 注意事项
+
+* 设置TTL,默认超时时间

project/benchmark.md → project/js/benchmark.md


+ 57 - 0
project/js/es6.md

@@ -0,0 +1,57 @@
+# ES 6/7
+
+## Async
+
+```js
+async function fn(args){
+  // ...
+}
+
+// 等同于
+
+function fn(args){
+  return spawn(function*() {
+    // ...
+  });
+}
+```
+
+多个`await`命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。
+
+```javascript
+let foo = await getFoo();
+let bar = await getBar();
+```
+
+上面代码中,`getFoo`和`getBar`是两个独立的异步操作(即互不依赖),被写成继发关系。这样比较耗时,因为只有`getFoo`完成以后,才会执行`getBar`,完全可以让它们同时触发。
+
+```javascript
+// 写法一
+let [foo, bar] = await Promise.all([getFoo(), getBar()]);
+
+// 写法二
+let fooPromise = getFoo();
+let barPromise = getBar();
+let foo = await fooPromise;
+let bar = await barPromise;
+```
+
+上面两种写法,`getFoo`和`getBar`都是同时触发,这样就会缩短程序的执行时间。
+
+## Proxy
+
+```bash
+node --harmony-proxies
+```
+
+示例代码:
+
+```js
+const proxy = new Proxy({}, {
+  get: (target, property) =>
+    (test) => [target, property, test]
+});
+
+console.log(proxy.func);          // [Function]
+console.log(proxy.func('123'));   // [ {}, 'func', '123' ]
+```

+ 86 - 0
project/test.md

@@ -157,3 +157,89 @@ describe('Demo', function () {
 	});
 });
 ```
+
+ES6 下的 BDD 测试示例对比:
+
+```js
+import {test, server, assert} from './_import';
+let location;
+test.before(async() => {
+  const response = await server.inject({
+    method: 'POST',
+    url: '/login',
+    payload: {
+      username: 'willin',
+      password: 'PASSWORD'
+    }
+  });
+  location = response.headers.location;
+});
+
+test('GET / 302', async() => {
+  const response = await server.inject({
+    method: 'GET',
+    url: '/'
+  });
+  assert.equal(response.statusCode, 302);
+});
+
+test('GET /login 200', async() => {
+  const response = await server.inject({
+    method: 'GET',
+    url: '/login'
+  });
+  assert.equal(response.statusCode, 200);
+});
+
+
+test('POST /login 302', async() => {
+  const response = await server.inject({
+    method: 'POST',
+    url: '/login',
+    payload: {
+      username: 'willin',
+      password: 'PASSWORD'
+    }
+  });
+  assert.equal(response.statusCode, 302);
+});
+
+test('POST /login 401', async() => {
+  const response = await server.inject({
+    method: 'POST',
+    url: '/login',
+    payload: {
+      username: 'willin',
+      password: 'Ww10842073305zZa28v3PO5Ok0L63IdA'
+    }
+  });
+  assert.equal(response.statusCode, 401);
+});
+
+test('POST /login Invalid Params 403', async() => {
+  const response = await server.inject({
+    method: 'POST',
+    url: '/login',
+    payload: {
+      username: 'willin'
+    }
+  });
+  assert.equal(response.statusCode, 403);
+});
+
+test('GET /doc 200', async() => {
+  const response = await server.inject({
+    method: 'GET',
+    url: location
+  });
+  assert.equal(response.statusCode, 200);
+});
+
+test('GET /doc 302', async() => {
+  const response = await server.inject({
+    method: 'GET',
+    url: '/doc?'
+  });
+  assert.equal(response.statusCode, 302);
+});
+```