Author: elilevine
Date: Wed Aug 27 18:26:23 2014
New Revision: 1620952
URL: http://svn.apache.org/r1620952
Log:
Update multi-tenancy docs for PHOENIX-1204
Modified:
phoenix/site/publish/multi-tenancy.html
phoenix/site/source/src/site/markdown/multi-tenancy.md
Modified: phoenix/site/publish/multi-tenancy.html
URL:
http://svn.apache.org/viewvc/phoenix/site/publish/multi-tenancy.html?rev=1620952&r1=1620951&r2=1620952&view=diff
==============================================================================
--- phoenix/site/publish/multi-tenancy.html (original)
+++ phoenix/site/publish/multi-tenancy.html Wed Aug 27 18:26:23 2014
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<!--
- Generated by Apache Maven Doxia at 2014-08-18
+ Generated by Apache Maven Doxia at 2014-08-26
Rendered using Reflow Maven Skin 1.1.0
(http://andriusvelykis.github.io/reflow-maven-skin)
-->
<html xml:lang="en" lang="en">
@@ -124,30 +124,34 @@
<div class="page-header">
<h1>Multi tenancy</h1>
</div>
-<p>Support for multi-tenancy is built on top of the concepts of a <a
href="views.html">VIEW</a> in Phoenix. Users create a logical tenant-specific
table as a VIEW and query and update it just like with regular Phoenix tables.
Data in these tenant-specific tables resides in a shared, regular Phoenix table
(and thus in a shared HBase table) that is declared at table creation time to
support multi-tenancy. All tenant-specific Phoenix tables whose data resides in
the same physical HBase table have the same primary key structure but each
tenantâs table can contain any number of non-PK columns unique to it. The
main advantages afforded by this feature are:</p>
-<ol style="list-style-type: decimal">
- <li>It implements physical tenant data isolation, including automatically
constraining tenants to only work with data that âbelongsâ to the each
tenant.</li>
- <li>It prevents a proliferation of HBase tables, minimizing operational
complexity.</li>
-</ol>
<div class="section">
<div class="section">
+ <h3 id="Highlights">Highlights</h3>
+ <ul>
+ <li>Multi-tenancy in Phoenix works via a combination of multi-tenant tables
and tenant-specific connections (detailed below).</li>
+ <li>Tenants open tenant-specific connections to Phoenix. These connections
can only access data that belongs to the tenant.</li>
+ <li>Tenants only see their own data in multi-tenant tables and can see all
data in regular tables.</li>
+ <li>In order to add their own columns, tenants create tanant-specific views
on top of multi-tenant tables and add their own columns to the views.</li>
+ </ul>
+ </div>
+ <div class="section">
<h3 id="Multi-tenant_tables">Multi-tenant tables</h3>
- <p>The first primary key column of the physical multi-tenant table must be
used to identify the tenant. For example:</p>
+ <p>Multi-tenant tables in Phoenix are regular tables that are declared using
the MULTI_TENANT=true DDL property. They work in conjuntion with
tenant-specific connections (detailed below) to ensure that tenats only see
their data in such tables. The first primary key column of multi-tenant tables
identifies the tenant. For example:</p>
<div class="source">
<pre>CREATE TABLE base.event (tenant_id VARCHAR, event_type CHAR(1),
created_date DATE, event_id BIGINT)
MULTI_TENANT=true;
</pre>
</div>
- <p>In this case, the tenant_id column identifies the tenant and the table is
declared to be multi-tenant. The column that identifies the tenant may be given
any name, but must of type VARCHAR or CHAR.</p>
+ <p>The column that identifies the tenant may be given any name, but must of
type VARCHAR or CHAR. Regular Phoenix connections work with such tables with no
constraints, including working with data across tenant boundaries.</p>
</div>
<div class="section">
- <h3 id="Tenant-specific_Tables">Tenant-specific Tables</h3>
- <p>Tenants are identified by the presence or absence of a TenantId property
at JDBC connection-time. A connection with a non-null TenantId is considered a
tenant-specific connection. A connection with an unspecified or null TenantId
is a regular connection. A tenant specific connection may only query:</p>
+ <h3 id="Tenant-specific_Connections">Tenant-specific Connections</h3>
+ <p>Tenants are identified by the presence or absence of the TenantId
property at JDBC connection-time. A connection with a non-null TenantId is
considered a tenant-specific connection. A connection with an unspecified or
null TenantId is a regular connection. A tenant-specific connection may only
query:</p>
<ul>
- <li><b>their own schema</b>, which is to say it only sees tenant-specific
views that were created by that tenant.</li>
- <li><b>non multi-tenant global tables</b>, that is tables created with a
regular connection without the MULTI_TENANT=TRUE declaration.</li>
+ <li><b>all data in non-multi-tenant (global) tables</b>, that is tables
created with a regular connection without the MULTI_TENANT=true
declaration.</li>
+ <li><b>their own data in multi-tenant tables</b>.</li>
+ <li><b>their own schema</b>, which is to say it only sees tenant-specific
views that were created by that tenant (detailed below).</li>
</ul>
- <p>Tenant-specific views may only be created using a tenant-specific
connection and the base table must be a multi-tenant table. Regular connections
are used to create global tables, including those that can be used as base
tables for tenant-specific tables.</p>
<p>For example, a tenant-specific connection is established like this:</p>
<div class="source">
<pre>Properties props = new Properties();
@@ -155,13 +159,15 @@ props.setProperty("TenantId",
Connection conn = DriverManager.getConnection("localhost", props);
</pre>
</div>
- <p>through which a tenant-specific table may be defined like this:</p>
+ </div>
+ <div class="section">
+ <h3 id="Tenant-specific_Views_optional">Tenant-specific Views
(optional)</h3>
+ <p>Tenant-specific views may only be created using tenant-specific
connections. They are created the same way as views. The base table must be a
multi-tenant table or another view that eventually points to one:</p>
<div class="source">
<pre>CREATE VIEW acme.event AS
SELECT * FROM base.event;
</pre>
</div>
- <p>The tenant_id column is neither visible nor accessible to a
tenant-specific view. Any reference to it will cause a
ColumnNotFoundException.</p>
<p>Alternately, a WHERE clause may be specified to further constrain the
data as well:</p>
<div class="source">
<pre>CREATE VIEW acme.login_event AS
@@ -169,11 +175,11 @@ SELECT * FROM base.event
WHERE event_type='L';
</pre>
</div>
- <p>Just like any other Phoenix view, whether or not this view is updatable
is based on the rules explained <a href="views.html#Updatable_Views">here</a>.
In addition, indexes may be added to tenant-specific tables just like with
regular tables.</p>
+ <p>The tenant_id column is neither visible nor accessible to a
tenant-specific view. Any reference to it will cause a ColumnNotFoundException.
Just like any other Phoenix view, whether or not this view is updatable is
based on the rules explained <a href="views.html#Updatable_Views">here</a>. In
addition, indexes may be added to tenant-specific views just like to regular
tables and views.</p>
</div>
<div class="section">
<h3 id="Tenant_Data_Isolation">Tenant Data Isolation</h3>
- <p>Any DML or query that is performed on a tenant-specific table is
automatically constrained to only operate on the tenantâs data. For the
upsert operation, this means that Phoenix automatically populates the tenantId
column with the tenantâs id specified at connection-time. For querying and
delete, a where clause is transparently added to constrain the operations to
only see data belonging to the current tenant.</p>
+ <p>Any DML or query that is performed on multi-tenant tables using a
tenant-specific connections is automatically constrained to only operate on the
tenantâs data. For the upsert operation, this means that Phoenix
automatically populates the tenantId column with the tenantâs id specified at
connection-time. For querying and delete, a where clause is transparently added
to constrain the operations to only see data belonging to the current
tenant.</p>
</div>
</div>
</div>
Modified: phoenix/site/source/src/site/markdown/multi-tenancy.md
URL:
http://svn.apache.org/viewvc/phoenix/site/source/src/site/markdown/multi-tenancy.md?rev=1620952&r1=1620951&r2=1620952&view=diff
==============================================================================
--- phoenix/site/source/src/site/markdown/multi-tenancy.md (original)
+++ phoenix/site/source/src/site/markdown/multi-tenancy.md Wed Aug 27 18:26:23
2014
@@ -1,25 +1,25 @@
# Multi tenancy
-Support for multi-tenancy is built on top of the concepts of a
[VIEW](views.html) in Phoenix. Users create a logical tenant-specific table as
a VIEW and query and update it just like with regular Phoenix tables. Data in
these tenant-specific tables resides in a shared, regular Phoenix table (and
thus in a shared HBase table) that is declared at table creation time to
support multi-tenancy. All tenant-specific Phoenix tables whose data resides in
the same physical HBase table have the same primary key structure but each
tenantâs table can contain any number of non-PK columns unique to it. The
main advantages afforded by this feature are:
-
-1. It implements physical tenant data isolation, including automatically
constraining tenants to only work with data that âbelongsâ to the each
tenant.
-2. It prevents a proliferation of HBase tables, minimizing operational
complexity.
+### Highlights
+* Multi-tenancy in Phoenix works via a combination of multi-tenant tables and
tenant-specific connections (detailed below).
+* Tenants open tenant-specific connections to Phoenix. These connections can
only access data that belongs to the tenant.
+* Tenants only see their own data in multi-tenant tables and can see all data
in regular tables.
+* In order to add their own columns, tenants create tanant-specific views on
top of multi-tenant tables and add their own columns to the views.
### Multi-tenant tables
-The first primary key column of the physical multi-tenant table must be used
to identify the tenant. For example:
+Multi-tenant tables in Phoenix are regular tables that are declared using the
MULTI_TENANT=true DDL property. They work in conjuntion with tenant-specific
connections (detailed below) to ensure that tenats only see their data in such
tables. The first primary key column of multi-tenant tables identifies the
tenant. For example:
CREATE TABLE base.event (tenant_id VARCHAR, event_type CHAR(1),
created_date DATE, event_id BIGINT)
MULTI_TENANT=true;
-In this case, the tenant_id column identifies the tenant and the table is
declared to be multi-tenant. The column that identifies the tenant may be given
any name, but must of type VARCHAR or CHAR.
-
-### Tenant-specific Tables
-Tenants are identified by the presence or absence of a TenantId property at
JDBC connection-time. A connection with a non-null TenantId is considered a
tenant-specific connection. A connection with an unspecified or null TenantId
is a regular connection. A tenant specific connection may only query:
+The column that identifies the tenant may be given any name, but must of type
VARCHAR or CHAR. Regular Phoenix connections work with such tables with no
constraints, including working with data across tenant boundaries.
-* **their own schema**, which is to say it only sees tenant-specific views
that were created by that tenant.
-* **non multi-tenant global tables**, that is tables created with a regular
connection without the MULTI_TENANT=TRUE declaration.
+### Tenant-specific Connections
+Tenants are identified by the presence or absence of the TenantId property at
JDBC connection-time. A connection with a non-null TenantId is considered a
tenant-specific connection. A connection with an unspecified or null TenantId
is a regular connection. A tenant-specific connection may only query:
-Tenant-specific views may only be created using a tenant-specific connection
and the base table must be a multi-tenant table. Regular connections are used
to create global tables, including those that can be used as base tables for
tenant-specific tables.
+* **all data in non-multi-tenant (global) tables**, that is tables created
with a regular connection without the MULTI_TENANT=true declaration.
+* **their own data in multi-tenant tables**.
+* **their own schema**, which is to say it only sees tenant-specific views
that were created by that tenant (detailed below).
For example, a tenant-specific connection is established like this:
@@ -27,20 +27,19 @@ For example, a tenant-specific connectio
props.setProperty("TenantId", "Acme");
Connection conn = DriverManager.getConnection("localhost", props);
-through which a tenant-specific table may be defined like this:
+### Tenant-specific Views (optional)
+Tenant-specific views may only be created using tenant-specific connections.
They are created the same way as views. The base table must be a multi-tenant
table or another view that eventually points to one:
CREATE VIEW acme.event AS
SELECT * FROM base.event;
-The tenant_id column is neither visible nor accessible to a tenant-specific
view. Any reference to it will cause a ColumnNotFoundException.
-
Alternately, a WHERE clause may be specified to further constrain the data as
well:
CREATE VIEW acme.login_event AS
SELECT * FROM base.event
WHERE event_type='L';
-Just like any other Phoenix view, whether or not this view is updatable is
based on the rules explained [here](views.html#Updatable_Views). In addition,
indexes may be added to tenant-specific tables just like with regular tables.
+The tenant_id column is neither visible nor accessible to a tenant-specific
view. Any reference to it will cause a ColumnNotFoundException. Just like any
other Phoenix view, whether or not this view is updatable is based on the rules
explained [here](views.html#Updatable_Views). In addition, indexes may be added
to tenant-specific views just like to regular tables and views.
### Tenant Data Isolation
-Any DML or query that is performed on a tenant-specific table is automatically
constrained to only operate on the tenantâs data. For the upsert operation,
this means that Phoenix automatically populates the tenantId column with the
tenantâs id specified at connection-time. For querying and delete, a where
clause is transparently added to constrain the operations to only see data
belonging to the current tenant.
+Any DML or query that is performed on multi-tenant tables using a
tenant-specific connections is automatically constrained to only operate on the
tenantâs data. For the upsert operation, this means that Phoenix
automatically populates the tenantId column with the tenantâs id specified at
connection-time. For querying and delete, a where clause is transparently added
to constrain the operations to only see data belonging to the current tenant.