2010-05-17 3 views
4

여러 가지면에서 멀티 테넌트 환경으로 간주 될 수있는 웹 응용 프로그램이 있습니다. 이 말은 응용 프로그램의 각 사용자가 자신의 '사용자 지정'환경을 가지며 해당 사용자간에 전혀 상호 작용이 없음을 의미합니다.많은 사용자를위한 많은 테이블?

지금까지 웹 응용 프로그램을 '단일 사용자'환경으로 구축했습니다. 즉, 실제로 다중 사용자를 지원하는 데 아무 것도하지 않았지만 앱에서 원하는 기능 만 수행했습니다. 다음은 내 문제입니다. 다중 사용자 환경을 구축하는 가장 좋은 방법은 무엇입니까?

  1. 모든 사용자가 동일한 '코어'백엔드를 가리 킵니다. 즉, 적절한 SQL 쿼리를 통해 사용자를 구분하는 논리를 작성합니다 (예 : select * from table where user = '123'및 attribute = '456').
  2. 각 사용자는 고유 한 테이블 공간을 가리키며 시스템에 참여할 때 별도로 작성됩니다. 이 경우 사용자 당 몇 가지 종류의 접미어를 사용하여 모든 관련 SQL 테이블을 생성합니다. (예 : 쿼리는 'select * from table_ from attribute ='456 '과 같이 나타납니다.)

요약하면 "select * from table where USER ="및 "select * from table_USER"의 차이점입니다.

+0

나는 각 사용자가 고유 한 데이터베이스 테이블을 가지고 있음을 이해하고 있습니까? 이것의 목적은 무엇입니까? –

+0

"select * from table where USER = .."방법으로 이동하십시오. 또한 OR/M을 사용하여 직접 SQL을 작성하는 것이 좋습니다.이 방법을 사용하면 왜 접근 방식이 더 나은지 (즉, 1 사용자 클래스, 여러 사용자 객체) 분명해야합니다.) – tarn

답변

4

테이블을 동적으로 생성하는 것은 다소 지저분하고 혼란 스럽습니다. 또한 많은 사용자가있는 경우 테이블 수가 많으면 혼란에 빠질 수 있습니다. 특히 단일 테이블 대신 n 개의 테이블을 변경해야하는 경우 특히 그렇습니다.

-> 하나의 테이블을 사용하고 user_id 열을 추가하십시오. 적절한 인덱스를 사용하면 별도의 테이블보다 빠르거나 빠릅니다.

0

각 테넌트에 대해 별도의 테이블을 만드는 유일한 방법은 각 테넌트마다 별도의 데이터베이스가있는 경우입니다.이 경우 테이블은 여전히 ​​동일한 이름을 갖게됩니다.

그렇지 않으면 각 엔티티에 대해 하나의 테이블을 사용하고 테넌트 ID별로 필터링하십시오.

2

첫 번째 옵션이 더 좋습니다.

일반적으로 표에는 정규화 된 데이터가 있어야하며 동일한 표를 복제해서는 안됩니다. 만들거나 프로그램이 SQL 서버에있는 경우

0

에 실제 테이블을 드롭 할 수있는 기능을 부여 할 필요가 없기 때문에

은 또한 첫번째 옵션은, 나는 모든 세입자에 대한 하나의 테이블을 사용하는 것이 좋습니다, 안전 응용 프로그램이 사용하는 로그인에 대한 기본 테이블에 대한 액세스 권한을 부여하지 않고 인라인 테이블 값 함수에 대한 액세스를 제한합니다. 이 단지 매개 변수 뷰처럼, 이들에 접근 할 수있는 아무도 단일 호출에서 하나 이상의 세입자를위한 세트를 검색 할 수 없음을 의미한다 (그래서 실수로 다른 사람의 제품 카탈로그에 조인하지 않음) :

CREATE TABLE [dbo].[mt](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [TenantID] [int] NOT NULL, 
    [BusinessKey] [varchar](50) NOT NULL, 
CONSTRAINT [PK_mt] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
), 
CONSTRAINT [IX_mt] UNIQUE NONCLUSTERED 
(
    [TenantID] ASC, 
    [BusinessKey] ASC 
)) 

CREATE FUNCTION f_mt (@TenantID AS INT) 
RETURNS TABLE 
AS 
RETURN 
    (SELECT * 
     FROM  mt 
     WHERE  TenantID = @TenantID 
    ) 

하는 경우

CREATE VIEW vw_mt 
AS 
    SELECT * 
    FROM f_mt(CONTEXT_INFO()) 

그것은 모두 당신이이 문제를 넣어하는 방법을 많이 추상화 따라 달라집니다 당신은 (() CONTEXT_INFO 사용)가있는 랩이 간단한 전망을하는 것도 가능 연결 어딘가에 저장되어있는 TenantID 있습니다.

1

귀하의 선택에 달려 있습니다.당신은 정말 세 가지 선택이 있습니다

하나의 데이터베이스 그들 모두를 지배하는 ... (선택 1)

물론 추가, TenantId 열이 새로운 세입자 (사용자)를 추가 할 쉽게를하지만 몇 가지 단점이있다 :

  1. 모든 쿼리가 TenantId에 대해 필터링되도록주의해야합니다. TenantId를 우연히 잊고 다른 임차인의 데이터를 반환하는 것은 매우 쉽습니다.
  2. 모든 최상위 수준의 부모 테이블에는 TenantId가 포함되어야합니다. 귀하의 주요 데이터뿐만 아니라 모든 임차인 특정 부모 데이터입니다.
  3. 다른 시간대에 다른 스키마 버전을 사용할 수 없습니다. 예를 들어, 응용 프로그램의 버전 1.1에서 일부 데이터 스키마 변경을 수행한다고 가정합니다. 모든 임차인이 동일한 데이터베이스에있는 경우 원하는지 여부에 관계없이 모든 사람이 동시에 업데이트해야합니다. 또한 단일 데이터베이스를 사용하는 경우 거의 동일한 사이트를 사용하여 사이트와 스키마를 동기화 상태로 유지해야합니다. 이렇게하면 새 기능을 얻기 위해 누군가 업그레이드 요금을 청구 할 수 없습니다. 기능은 플러그 - 인으로 빌드해야합니다. 버전 특정 업데이트와 달리 나쁜 것은 아니지만 처음부터 의식적인 결정을 내려야합니다.
  4. 데이터 복사본을 갖고 싶거나 자신의 데이터를 호스팅하려는 경우 또는 다른 데이터베이스 서버로 이동하려는 경우 세입자의 데이터를 분리해야 할 수 있습니다. 모든 리소스가 공유되기 때문에 하나의 세입자가 보고서 나 트래픽을 통해 리소스를 씹어 서 자신의 데이터베이스 서버로 옮기고 (이 혜택을 상향 판매하는) 상황에 처할 수 있습니다. 또한, 나는 세입자들이 자신들이 다운로드 할 수있는 데이터 사본을 원할 때 상황에 부딪혔다. 모든 데이터가 하나의 데이터베이스에 있다면, 이것은 일종의 일이 될 수 있습니다.

법인 고객에게 판매하려는 경우이 경로를 선택하지 않아도됩니다. 그러나 수천 명의 최종 사용자에게 데이터를 제공 할 필요가없는 세입자로 수천 명을 추가하려는 경우 단일 데이터베이스를 사용하는 것이 올바른 방법 일 것입니다. 스키마에 의해

세그먼트 세입자 (예 Tenant1.Table1, Tenant1.Table2 ... Tenant2.Table1, Tenant2.Table2 ...)

IMO, 이것은 어렵습니다 (나는 당신의 선택이 믿는) 단순히 별도의 데이터베이스를 사용하는 버전. 하나의 데이터베이스를 유지 관리하는 것이 약간 쉽지만 별도의 데이터베이스를 사용할 때와 동일한 문제가 발생한다는 이점이 있습니다. 기업 고객의 경우 데이터베이스

세그먼트 세입자, 나는 결국이 간단한을 밝혀 것으로 나타났습니다. 이는 연결 문자열이 잘못되지 않는 한 세입자가 잘못된 데이터를 볼 가능성을 제거합니다. 기업은 자체 시스템을 호스팅 할 수 있습니다. 세입자별로 다른 가상 응용 프로그램을 사용하는 경우 세입자가 다른 버전에있을 수 있습니다. 따라서 리소스 할당, 백업 및 복원 작업을 쉽게 수행 할 수 있습니다. 그것은 단지 (그러나 중요하지 않은) 단점은 셋업 시간 비용 (그리고 따라서 재정적 비용)이다. 새로운 클라이언트를 얻을 때 데이터베이스를 추가하는 것은 어려울 수 있습니다. 기술적으로는 자동화가 가능하지만 여전히 고통스런 일입니다.

결국 결국 타겟 고객에 따라 다릅니다. 만약 그들이 표준 사용자라면, 나는 "그들 모두를 통치하는 하나의 데이터베이스"접근법을 사용하여 많은 코드 리뷰와 자동화 된 테스트를 수행 할 것입니다.기업 고객, 특히 대기업 고객 인 경우 세입자별로 데이터베이스를 별도로 고려할 것입니다.

관련 문제