为多租户进行数据库设计
我们需要分割表或者应用程序的原因有很多,例如安全性、资源控制,或者易用性等。不管是出于什么原因,我们都需要经常将表分成多个组(为了不混淆,避免使用“数据库”这个词)。
这个话题将此和多租户(multitenancy)的话题联系一起,尽管数据库租用在目前还不是很被接受。
该如何做???
如果你想在一台服务器中运行多个物理数据库,那么有四个主要的方案可供选择:
方案1:在一个PostgreSQL实例的一个互数据库中的不同schema中创建表(参考“使用多个模式”);
方案2:在一个PostgreSQL实例中创建多个数据库(参考“单独给用户分配数据库”);
方案3:在同一台物理机或者虚拟机中创建多个PostgreSQL实例(参考“在一个系统运行多个服务”);
方案4:在同一台物理机上创建多个虚拟机,然后这些虚拟机分别创建PostgreSQL实例。
那种方式最好?答案源于需求,如:
如果我们的目标是将物理资源分离,那么方案3和方案4是最好的。单独的数据服务可以很容易地分配不同的磁盘,内存也可以单独分配,当我们需要关闭或者启动服务时不会影响其他人。
如果我们的目标是安全性,那么方案2就足够了。
如果我们的目标仅是为了管理需要将表进行分组,那么方案1或者方案2就很好。
出于安全的原因,方案2允许完全隔离。这防止了某个用户在有权限访问多组表时尝试关联他们的情况。因此如果以后有可能有关联分析的情况,则可以考虑选用方案1,尽管这种计算分析应该考虑放在独立的数据仓库中而不是生产数据库中。
方案3对于很多PostgreSQL的发行版都有一个难点。数据库的默认安装通常使用一个固定位置用于存放数据库,这使得配置以实现这个方案有点麻烦。Ubuntu/Debian在这方面处理得比较好,因此该方案在这些系统下比较有吸引力。
使用多个模式(schema)
我们可以把一组表划分到它们自己的“命名空间”,也就是PostgreSQL的“模式(schema)”中。
该如何做???
schema的创建非常简单,命令如下:
CREATE SCHEMA finance;
CREATE SCHEMA sales;
然后,我们可以直接使用带schema的“完整名称”创建对象,如下:
REATE TABLE finance.month_end_snapshot (...)
数据库对象创建的默认schema被称为当前schema。我们可以通过以下查询到哪一个是当前schema;
postgres=# select current_schema;
返回的输出如下:
current_schema
--------------------
public
(1 row)
当我们访问数据库对象时,我们使用用户可设置的参数search_path来标记我们要搜索的schema。前schema是最先搜索的,没有单独的参数来设置它。
因此,如果我们想让某个用户访问某组表,我们可以修改它的search_path参数,可以为每个用户设置这个参数,因为这个参数可以在用户连接上时进行设置。对应的SQL为:
ALTER ROLE fiona SET search_path = 'finance';
ALTER ROLE sally SET search_path = 'sales';
注意,public schema没有包含在search_path中,因此不会被搜索。fiona用户创建的所有表默认都在finance schema中,而sally创建的所有表默认都在sales schema中。
可以访问finance 和sales 的用户也可以看到并通过search_path使用数据库中的其他schema,但我们可以授予或者取消相关权限,使他们既不能在其他schema中创建对象,也不能读取其他schema中的数据:
REVOKE ALL ON SCHEMA finance FROM public;
GRANT ALL ON SCHEMA finance TO fiona;
REVOKE ALL ON SCHEMA sales FROM public;
GRANT ALL ON SCHEMA sales TO sally;
还有一种做法是仅允许一个用户在指定模式中创建对象,但是拥有其他模式的usage权限。我们可以做如下设置:
REVOKE ALL ON SCHEMA finance FROM public;
GRANT USAGE ON SCHEMA finance TO fiona;
GRANT CREATE ON SCHEMA finance TO fiona;
REVOKE ALL ON SCHEMA sales FROM public;
GRANT USAGE ON SCHEMA sales TO sally;
GRANT CREATE ON SCHEMA sales TO sally;
注意,你需要指定这个schema的使用权限,同时需要为这个schema中的对象指定适当权限。因此,你需要为对象赋予指定权限,例如:
CRANT SELECT ON month_end_snapshot TO public;
也可以设置用户的默认权限,这样在对象被创建的时候他们即可自动获得该权限:
ALTER DEFAULT PRIVILEGES FOR USER fiona IN SCHEMA finance
GRANT SELECT ON TABLES TO PUBLIC;
如何实现的???
PostgreSQL的search_path概念类似于PATH环境变量。
PostgreSQL的当前schema的概念类似于当前工作目录的概念。只是没有类似的“cd” 命令用于切换目录。当前工作路径的改变有serach_path控制。
还有一些其他的差异,eg:PostgreSQL的schema 的结构不像文件目录一样是层级结构。
很多人都会创建于用户名同名的schema ,这使得器工作方式和其他关系型数据库(eg.Oracle)的工作方式一样。
注意,finance和 sales 模式位于同一个PostgreSQL 数据库中,并且运行在同一个数据库服务中。它们使用相同的缓冲池,同时还有许多其他全局参数对这两个紧密联系在一起的schema 同时生效。
###参考文献:PostgreSQL 9 Administration Cookbook(第2版)中文版###
38.快速删除工作表中的空行
如果用户想删除Excel工作表中的空行,一般的方法是需要将空行都找出来,然后逐行删除,但这样做操作量非常大,很不方便。下面提供一种快速删除工作表中的空行的方法:首先打开要删除空行的工作表,在打开的工作表中单击“插入→列”命令,从而插入一新的列X,在X列中顺序填入整数,然后根据其他任何一列将表中的行排序,使所有空行都集中到表的底部。删去所有空行中X列的数据,以X列重新排序,然后删去X列。
39.绘制斜线表头
一般情况下在Excel中制作表头,都把表格的第一行作为表头,然后输入文字。不过,这样的表头比较简单,更谈不上斜线表头了。能不能在Excel中可以实现斜线表头,下面就是具体的方法: 由于作为斜线表头的单元格都要比其他单元格大,所以首先将表格中第一个单元大小调整好。然后单击选中单元格,单击“格式→单元格”命令,弹出“单元格格式”窗口,选择“对齐”标签,将垂直对齐的方式选择为“靠上”,将“文本控制”下面的“自动换行”复选框选中(),再选择“边框”标签,按下“外边框”按钮,使表头外框有线,接着再按下面的“斜线”按钮,为此单元格添加一格对角线(),设置好后,单击“确定”按钮,这时Excel的第一个单元格中将多出一个对角线。现在双击第一单元格,进入编辑状态,并输入文字,如“项目”、“月份”,接着将光标放在“项”字前面,连续按空格键,使这4个字向后移动(因为我们在单元格属性中已经将文本控制设置为“自动换行”,所以当“月份”两字超过单元格时,将自动换到下一行)。现在单击表格中任何一处,退出第一单元格看看,一个漂亮的斜线表头就完成了。
40.绘制斜线单元格
利用Excel“边框”选项卡的两个斜线按钮,可以在单元格中画左、右斜线。如果想在单元格中画多条斜线,就必须利用“绘图”工具,方法是:打开Excel的“绘图”工具,单击“直线”按钮,待光标变成小十字后拖动光标,即可画出需要的多条斜线。只要画法正确,斜线可随单元格自动伸长或缩短。至于斜线单元格的其他表格线,仍然按上面介绍的方法添加。当然,斜线单元格的数据输入要麻烦一些,通常的做法是让数据在单元格内换行(按“Alt+回车键”),再添加空格即可将数据放到合适位置。
领取专属 10元无门槛券
私享最新 技术干货