2019年8月

README.md

后台管理系统结构说明

引入服务端入口(管理后台接口)

  • 初始化管理后台 Manager对象

    • 处理登录、鉴权
    • 处理默认访问路径
    • 初始化权限
  • 引入页面文件

    • header HTML头文件
    • customHeader (自定义)
    • aside 侧边栏导航菜单
    • customAside (自定义)
    • act ( page | default ) 核心内容输出 优先page路径
    • script 通用脚本
    • customFooter 自定义脚本
    • footer HTML底部 ( act页customJS在这里生效 )

系统用户的默认权限设置

90000 超级管理员 80000 管理员

40000 网站编辑 30000 创作者 10000 普通用户

redis没有表的概念

由于没有数据表的概念、我们很多基于关系型数据库的查询方式、在Redis服务器上就要有新的思路。 譬如说我们通过4张表来维护用户数据、在redis上就应该只使用一个Hash 另外类似于Comment这样的表,我们就需要设计成Redis List类型 以COMMET_USERID来作为key 每一次添加一条反序列化数据进去。但这样做面临的问题是我们无法使用关系型表的其他诸如合并查询、反向查询等查询功能。

redis服务密码验证访问

配置文件中配置 requirepass yourpassword

数据库层级的访问控制

目前没有方案 考虑中 这个部分也和java服务端的朋友讨论过,Redis确实没有这方面的支持,如果考虑同一个redis服务器中有多个或者大量Saas需求、那么比较好的方式就是在最前面加一个appid的索引。

探索一下几种实现方式:

# 以saasID作为key userid做其中一项的方式
hset TRFUnmsZ userid qFVqmqMz nickname sprite
hset gdYuSu4G userid hGE5REy2 nickname amber

# 以userid作为key saasid作为其中一项
hset qFVqmqMz saasid TRFUnmsZ nickname sprite
hset Lh8PCIVy saasid TRFUnmsZ nickname soki
hset gdYuSu4G saasid hGE5REy2 nickname amber

# 以saasid拼接 keyid的方式
hset TRFUnmsZ_qFVqmqMz nickname sprite
hset TRFUnmsZ_Lh8PCIVy nickname soki
hset hGE5REy2_gdYuSu4G nickname amber

hset TRFUnmsZ_SETTING WECHATID 123456
hset TRFUnmsZ_SETTING APPNAME AppSite
hset hGE5REy2_SETTING WECHATID 654321

基于Redis只能通过key进行查询、不能使用类似于MySQL的WHERE查询,所以用saasid作为key的方式被摒弃。我们不可能取出所有的saas下的数据 再到程序里查找。

- 阅读剩余部分 -

在macOS上安装php-redis是比较简单的,但是也有可能进入坑里,由于百度到的结果更坑,所以整理一下备用

1 安装redis

官方下载地址 https://redis.io/download 参考官方的说明、安装步骤是 手动下载或者使用终端wget下载tar包 下载完毕后解压并且打开目录

$ cd /User/sprite/Downloads/redis-5.0.5
$ make

安装完毕之后打开终端输入 redis-server 出现redis欢迎界面表示已经安装成功

使用redis-server启动redis服务之后不要关闭终端页面、测试的时候要另外打开一个终端、然后输入redis-cli 否则会报错 无法连接到redis服务器

2 安装phpredis扩展

大杀器 官方文档 phpredis-Github

参考官方的文档,我们可以采用pecl安装、我没有尝试。 使用编译安装的方式

2.1下载官方包到本地

https://github.com/phpredis/phpredis/releases

下载完毕后解压,建议把包转移到其他地方,防止后面清理下载文件夹清理掉。 比如说 我放到了 /Library/PhpExtra/redis-5.0.2 (可以随便放)

2.2 在终端打开这个目录
$ cd /Library/PhpExtra/redis-5.0.2/redis-5.0.2

一定要保证目录下有 configure文件

2.3 使用phpize进行安装

这一步是网上基本都错误的部分 phpize是一个可执行文件,路径一般在/usr/bin/下 如果我们的mac注册了php环境,那么我们直接输入phpize就可以 没有再切换目录的必要。

$ phpize ./configure --with-php-config=/usr/bin/php-config

如果这一步的时候,无法找到phpize我们再使用绝对路径来定位

$ /usr/bin/phpize ./configure --with-php-config=/usr/bin/php-config

可能发生的问题:

1.Cannot find autoconf. Please check your autoconf installation and the $PHP_AUTOCONF environment variable.Then, rerun this script.

brew install autoconf

2.mac phpize执行后报错:grep: /usr/include/php/main/php.h: No such file or directory

3.make: *** No targets specified and no makefile found.

如果phpize这一步成功了,不报错了。仍然有可能无法安装。比如说我就是这样。

无奈,尝试使用pecl方式安装。

一番折腾。 发现还是搞不定。 最终发现了是自己在2.3的步骤时候有错误。

划重点:

$ cd /Library/PhpExtra/redis-5.0.2/redis-5.0.2 # 切换到你解压的目录
$ phpize

Configuring for: PHP Api Version: 20160303 Zend Module Api No: 20160303 Zend Extension Api No: 320160303

这一步看不到版本号的,看上面错误参考2

$ ./configure

... configure: creating ./config.status config.status: creating config.h

$ make

... Build complete. Don't forget to run 'make test'.

$ make install

... Installing shared extensions: /usr/lib/php/extensions/no-debug-non-zts-20160303/ 最后一步会告诉你 扩展安装到了哪里,复制下来 去php的配置文件中添加

php.ini一般在 /etc/php.ini 如果你没有就复制一个 php.ini.default出来 最后加上:

extension_dir="/usr/lib/php/extensions/no-debug-non-zts-20160303"
extension=redis.so

保存重启apache

sudo apachectl restart

在网上可以查到有两种方式查询表的索引

show index from tablename
SELECT * FROM mysql.innodb_index_stats a WHERE a.database_name = '数据库名' and a.table_name like '%表名%';

第一种是可行的,问题是在于并不是用SELECT语句,所以就不能和其他的表数据一起查询,譬如说 查询表结构的时候连同索引一起查询。

(第二种来自于网络,实际上语句本身就有错误和低效的like,我们先只看逻辑) 仅看第二种也是不可行的,因为除了ROOT用户以外的用户无法访问innodb_index_stats表,所以是不行的。 在网上翻了很多页面都没有找到合适的解决方案,于是我把所有独立数据库用户身份可以查看的表全部翻看一遍之后发现。STATICS表中是存有索引数据的。

查询方式如下:

SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = basename AND TABLE_NAME = tablename

将索引信息和表结构信息一起查看的查询:

SELECT * FROM INFORMATION_SCHEMA.COLUMNS LEFT JOIN INFORMATION_SCHEMA.STATISTICS ON COLUMNS.COLUMN_NAME=STATISTICS.COLUMN_NAME AND COLUMNS.TABLE_NAME = STATISTICS.TABLE_NAME AND  STATISTICS.TABLE_SCHEMA = '{$basename}' AND STATISTICS.TABLE_NAME = '{$tablename}' WHERE COLUMNS.TABLE_SCHEMA = '{$basename}' AND COLUMNS.TABLE_NAME = '{$tablename}' 

这里一定要注意使用表内筛选 先将STATISTICS表中的数据过滤一遍,再进行合并,两张表都要以basename,tablename进行过滤。否则会有很大概率得到循环嵌套的大量结果!

  1. From:

mysql分别用数字INT和中文varchar做索引查询效率上差多少

性能相当

mysql中区别性能的是采用哪种索引方式,而不是索引的数据类型。

MySQL的btree索引和hash索引的区别

  1. hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,
  2. btree(B-Tree)索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,
  3. 综上,hash 索引的查询效率要远高于 btree(B-Tree) 索引。 虽然 hash 索引效率高,但是 hash 索引本身由于其特殊性也带来了很多限制和弊端,主要有以下这些。

- 阅读剩余部分 -

在一个大型的复杂应用中,我们通常会将不同模块的数据存储到各自的表中 例如在APPsite框架中我们默认了4张用户表 分别存储了 user_account 账户表 user_info 详情表 user_pocket 钱包表 user_group 分组表

这样我们在读写数据的时候可以做到表级别的隔离,防止一些api 或是 内外部方法导致的数据泄露问题,提高安全性和事务方法的紧密度。 当然也有一定的减轻单张表结构过于臃肿的作用。

这里的表拆分,要基于业务划分去做,譬如说详情、分组、钱包在用户的鉴权、登录包括收发消息等行为时都不需要,那么我们就可以将这些部分的数据转移到新的表中。保持account表的高效性。

于此对应的是我们在进行后台的丰富数据查询时就需要合并表进行查询,今天特意整理一下使用JOIN进行多表联合查询的注意点。

首先是最简单的范例

# JOIN查询 双表
SELECT * FROM user_account 
LEFT JOIN user_info ON user_account.userid = user_info.userid

在多表查询时,我们会遇到某个表 对应项目为空时的情况, 这时根据JOIN方式就会有不同的结果。其中INNER 方式就会取交集合并结果,而LEFT方式左表会完整展示,右表不满足条件的数据会被剔除为空。

- 阅读剩余部分 -

最近有将AppSite框架进行公开发布(开源)的想法。 不过开源也就意味着更多的一份责任,如果是普通的个人系统还好,我们的系统商业化在很多中大型项目上,安全也是一个隐忧。

暂且先梳理一下

Appsite的宗旨是用于快速开发网络\云应用\物联网

全栈支持引擎 Full stack Supporting Engine 介于CMS与Framework之间

AppSite主要思想是面向数据编程

从某个侧面来看计算机信息技术本身就是对于数据的各种处理,而AppSite就是这样的思想,我们的核心引擎着重解决的是提供一个可以自适应处理各种不同结构数据的一套程序开发套件。 基于这些高度自适应的基础功能,我们可以方便的创建各种方法或对象、进而快速实现不同的业务逻辑的新增或调整。

例如,我们对于向数据库添加数据的时候,通用的使用的是:

$DB->add( $data, $table );      // 数据库实例化操作方法
USER::add( $data );                 // 组件静态方法

这里相当于我们告诉程序 “我有这些数据,你添加一下。” 程序则通过设定好的规范自动去完成数据整理以及后续操作。

- 阅读剩余部分 -

Common Access System Design

最近在优化自己写的APPsite框架,其中一直以来没有妥善解决的权限模块可能是后面拓展出去的比较大的障碍。所以着手重写这个模块。 在现有的框架中ACCESS模块分为两大部分: 系统权限、单位权限两个。

系统权限主要用于验证系统功能是否可以执行。 主要支持了Token作用域验证功能,可以设置有效期、作用域、以及可执行次数。 ACCESS和密码验证不同,并不解决加密解密问题,只是负责一个权限的授予、验证、撤销的功能。

# 例1 手机改密码的流程:  作用域为 resetPassword
用户.发起请求 -> 
权限系统.开始流程 -> 
用户.提交验证 -> 
权限系统.验证(通过/拒绝)并授权(设置有效期) -> 
使用权限(一段时间有效 或 一次性有效)

单位权限类似于虚拟物品的所有权。支持以用户为单位的权限授权。 目前仅支持一种状态即 拥有( 可以访问、读取 ) 而写、删的权限仍然只归属于系统。

# 例2 虚拟商品包年授权:  
用户.发起购买 -> ... -> 支付验证成功 ->
权限系统.添加授权(设置有效期) ->
用户.拥有权限
----
客户端.查询授权 ->
权限系统.验证(通过|拒绝)并返回内容|错误 -> 
客户端.接收反馈 ->
用户.使用权限(获取内容等)

- 阅读剩余部分 -

在网上查看很多的帖子都是在 hypedown模块中注释掉对 \n 的解析 这样的做法是不行的,因为这样文章中的换行就会失效,所有的文字就堆到一起了。

查看了服务端的源代码并没有太好的解决方案,官方论坛所谓给出的已解决的开发板,我换了一下也并没有解决,这里先给一个临时解决方案。

在主题的footer中加入一行js代码即可

document.querySelectorAll(".post").forEach(function(post){ post.innerHTML = post.innerHTML.replace(RegExp(/<br><br>/g), '') });

主要就是检测同时出现两行的换行 就将它剔除掉 当然不完美,不过也没必要花太多时间在这个部分,大体上解决了问题~

最近自己鼓捣物联网的玩法,买了一个树莓派,打算通过自己的服务器来做数据通讯。 由于一直以来的框架都是php写的,所以仍然沿用php。 在使用soket的时候为了简化开发成本,扩展未来的可能性这里选用了workman来进行。