1. Database 관련 Naming Rule 

 

가.  Database Schema Name

1)   규칙

    Database Profile 이름을 의미함

    DB Alias 이름과 동일하게 

    영문 대문자로 작성함

    Database Short Name 길이는 최대 8자리를 넘을  없음

    Database Short Name  Site Unique Name 사용함

 

2)   표기 방식

<Database Short Name>
) TOURDB, ETKP, TKS

 

나.  Table Name

1)   규칙

    테이블임을 표시하기 위해 테이블  뒤에 _TB 라는 구분을 사용함

    테이블명은 대문자로 사용함

    시스템 구분 코드와 모듈구분코드로 업무 영역을 구분함

    의미있는 테이블명은 3단어까지 사용할  있음

    단어와 단어 사이는 _ 구성함

     단어는 최대 8자리까지 사용함

    구분명은 Table 특성을 나타냄

    예로는 Master, Detail, Control, Summary, Trigger, History 등이 있음

 

2)   표기 방식

<시스템 구분> + _ + <의미있는 테이블명> + _ + TB

) 사용자 테이블 : ACT_USERS_TB

 

다.  Column Name

1)   규칙

    물리명은 영문 대문자를 이용함. 논리명을 사용자가   있는 정도에서 명사  명사형동사를 사용함

    Column 대한 자리수는  12자리로 하며, 제한은 없음

, 사용하는 Database의 특성에 따라 제한될 수 있음

    Word Word 사이에는 _ 구분함

     Word 8자리를 넘을  없음

    모든 Column Dictionary List 등록된 약어사전  자료사전을 기초로 작성함

    Dictionary List 등록되지 않은 약어는 책임자의 동의 하에 등록함

    Column Name 약어의 조합으로 구성

    컬럼명에 컬럼을 대표하는 접미사를 사용하여 컬럼명의 성격을 나타냄.

 

2)   표기방식

<의미있는 컬럼명> 혹은 <의미있는 컬럼명> + _ + 접미사
종종 자주 사용하는 접미사는 다음과 같다.

접미사 내용 설명
_CD CODE 주로 코드 테이블의 코드, 각종 코드에 사용된다. 숫자나 문자로 이루어진 코드에 해당되며, 숫자나 문자의  부분이 의미가 있는 경우에 코드를 사용한다. 대부분 PK 해당한다.
) 대분류 코드 CTGRY_CD, 시도코드 SIDO_CD, 사용자 그룹 코드 USER_GROUP_CD 
_NM NAME 코드에 대한 명칭에 주로 사용된다. 논리명이 이름, 명칭인 경우에 해당된다.
) 사용자이름 USER_NM, 자원명 RES_NM,
중분류 코드명 DVSN_NM, 메뉴명 MENU_NM
_NO NUMBER 숫자로만 이루어진 경우, 주로 논리명이 번호인 경우에 사용.
) 주민등록번호 JUMIN_NO, 조문번호 JO_NO,
게시물번호 BOARD_NO
_SQ SEQUENCE 오라클의 Sequence, MSSQL Identity 경우에 사용한다. 숫자 일련번호로 PK 설정할 경우 SQ 사용한다. MSSQL Identity 경우 주로 _ID 사용하는 경우가 많은데, 사용자 아이디  USER_ID ID 의미가 틀려 SQ 사용한다.
) 작업번호 WORK_SQ, 이력번호 HISTORY_SQ
_ID ID 주로 사용자 아이디의 경우에 사용한다.
) 사용자아이디 USER_ID, 등록자아이디 REG_ID
_DT DATE 날짜의 경우 사용한다. DT 날짜 타입이 DATE형인 경우에만 사용한다. 보통 날짜의 경우 CHAR(8)형으로 20050718식으로 저장을 많이 한다. 이런 경우에는 _YMD 사용한다.
) 삭제일자 DEL_DT, 변경일자 CHG_DT
_YMD YYYYMMDD 날짜의 경우 사용한다. 날짜 타입이 CHAR 인경우 사용한다. 년월일인 경우 _YMD 사용하고, 년월형식으로 CHAR(6) 저장될 경우 _YM 사용한다. 년도, , 일자 인경우에는 YEAR, MONTH, DAY등의 컬럼명을 사용한다.
_GB 구분 구분값을 나타낼  사용한다. CD 주로 코드테이블을 별도로 사용할  적당하고, 테이블 없이 코드상에서 구별할  사용한다. 가령 사용자구분 필드가 있을  일반사용자, 내부사용자가 있다면 별도의 사용자 그룹테이블로 분리하여 사용할 경우 GROUP_CD 필드명이 되지만, 코드상에서 일반(G), 내부(I) 사용하기로 결정했다면 GROUP_GB 필드명을 사용하면 된다.
) 통계구분 STAT_GB
_ST STATE 상태값이다. 주로 CHAR(1) 형식을 사용한다.
) 사용자 상태 USER_ST
_FL FLAG 플레그값이다. 종종 삭제하지 않는 테이블에 삭제플레그를 많이 사용된다. 값은 0/1 이나 Y/N 많이 사용한다.
) 삭제여부 DEL_FL, 요청여부 REQ_FL
_ORD ORDER 순서를 나타낼  사용한다.
) 컬럼순서 COLUMN_ORD
_CNT COUNT ) 조회수 VIEW_CNT
_AMT AMOUNT ) 재고량 STOCK_AMT
_SUM SUM ) 분기합계 QTR_SUM, 년도합계 YEAR_SUM

 

 

3)   순서규칙

    기본적으로 관계형 모델에서 (Column) 순서는 의미가 없음. 그러나, 물리적인 형태로 생성되어 관리될 때에는 보다 효율적인 저장공간의 관리를 위해 다음 순서에 따라 우선순위를 결정함

    Primary Key 우선함

    Primary Key내에서는 Index 의미에 따라 순서를 결정함

    Not Null Columns 우선함

 

    Not Null Columns 내에서는 Foreign Key, Attributes 순서로 

    Null Columns 내에서는 다음의 규칙에 따라 순서를 결정함

    Fixed Length Columns 우선함(Date,Number,Char)

    Smaller Length Column 우선

 

라.  Index Name

1)   규칙

    해당하는 테이블명 뒤에 _IX 붙여 index임을 명확히 

    대문자를 사용함

    일련번호는 01 ~ 99까지 사용할  있음

    MSSQL 경우 클러스터드 인덱스와  클러스터드 인덱스를 구분하여 작성함. 클러스터드 인덱스 _IXC 사용하며,  클러스터드 인덱스는 일반 인덱스  룰을 따름.

    테이블에 인덱스가 하나만 존재할 경우 일련번호를 사용하지 않아도 .

 

2)   표기 방식

<시스템 구분> + _ + <의미있는 테이블명> + _ + IX{<일련번호>}

) Table I01_MASTER_TB Index : I01_MASTER_IX01

 

마.  Primary Key Name

1)   규칙

    영문 대문자로 작성함

    해당하는 테이블명의  뒤에 _PK라는 구분을 사용함

 

2)   표기방식

<시스템 구분> + _ + <의미있는 테이블명> + _ + PK

) Table  AC_USERS_TB Primary Key : AC_USERS_PK

 

바.  Foreign Key Name

1)   규칙

    영문 대문자로 작성함

    해당하는 테이블명의  뒤에 _FK라는 구분을 사용함

    일반적으로 테이블명과 컬럼명까지 사용하나, OBJECT 명칭이 길어져서 테이블명을 기준으로 작성함.

    일련번호 : 1 ~ 9

 

2)   표기방식

<시스템 구분> + _ + <의미있는 테이블명> + _ + FK{<일련번호>}

) Table  I01_MASTER_TB Foreign Key : I01_MASTER_FK1

 

사.  Stored Procedure Name

1)   규칙

    길이는  제한이 없으나 오라클의 OBJECT NAME 길이 제한은 있음.

    해당하는 테이블명의  뒤에 _SP라는 구분을 사용함

    기능명은 복수개 사용이 가능하면 3개의 단어를 넘지 않도록 

    기능을 나타내는 명칭이 하나일 경우 일련번호를 생략해도 .

    단어간에는 _ 구분함

    업무룰에 해당되지 않는, 혹은 특정 테이블에 해당되지 않는 DBMS 전반적인 프로시저의 경우, 시스템 프로시저로 작성하는 경우에는 시스템구분  테이블명을 생략하고 간단히 작성할  있다. ) 스키마 스크립트 GENERATION  GENERATE_SP

    오라클의 경우 패키지 내부의 프로시저의 경우 패키지 명칭에 시스템구분을 사용하므로, 프로시저나 함수명에 시스템구분 코드를 넣지 않는다. 또한 기능에 따른 일련번호를 사용하지 않고 OOP 기능인 Method Overloading  기능을 사용하여 작성한다. 또한 명칭은 Camel 표기법을 사용하여 작성한다. ) 사용자를 가져오는 경우 getUsers()

 

2)   표기방식

<시스템 구분> + _ + <의미있는 테이블명> + _ + <기능명>{<일련번호>} + _ + SP

) I01_MASTER_TB 테이블에서 데이타 입력에 대한 Procedure

    : I01_MASTER_INS01_SP

기능명 명칭 설명
INS INSERT 단일 테이블의 단순 INSERT 작업인 경우, 사용자 테이블에 데이터 입력 프로시저의 경우 업무룰이 복잡하여 여러 테이블에 걸쳐 삽입 작업이 된다면(서버측 트랜잭션이 구현된다면) INS 사용하지 않고, REG 사용한다.
UDT UPDATE 단일 테이블의 단순 UPDATE 작업의 경우
DEL DELETE 단일 테이블의 단순 삭제인 경우
LST LIST SELECT문을 사용하여 조회하는 경우
REG REGISTER 등록작업  트랜잭션을 사용하여 여러 테이블에 입력 작업이 이루어질 
MOD MODIFY 수정작업  트랜잭션을 사용하여 여러 테이블에 수정 작업이 이루어질 
REM REMOVE 삭제작업  트랜잭션을 사용하여 여러 테이블에 삭제 작업이 이루어  

 

    

아.  Function Name

1)   규칙

    길이는 제한이 없으며 영문 대문자를 사용함

    해당하는 테이블명의  뒤에 _FC라는 구분을 사용함을 원칙으로 하나, 함수명이 길어서 사용상 불편할 경우, 특정 시스템에 국한하지 않고, 항상사용하는 라이브러리 같은 함수의 경우 구분가능한 Short Name 사용해도 무방하다.

    단어간에는 _ 구분함

    시스템 함수로 작성한 경우에는 접미사를 사용하지 않고, 간략한 함수이름을 사용한다. ) INSTR, LEASTR(@x bigint, @y bigint) 

    오라클의 경우 패키지 내부의 함수의 경우에는 프로시저의 해당 규칙에 따른다.  시스템구분 코드와 접미사를 사용하지 않고, Camel 표기법으로 간략하게 작성한다.

 

2)   표기방식

<시스템 구분> + _ + <기능명> + _ + FC

) I01_MASTER_TB 테이블에서 주소명를 가져오기 위한 Function

    : I01_GET_ADDRESSNAME_FC(p_AddressCode IN Char) 내지는

: getAddressName(p_AddressCode IN Char)

 

자.  Table Trigger Name

1)   규칙

    영문 대문자로 작성함

    일련번호는 01 ~ 99까지 사용 가능함

 

2)   표기방식

<시스템 구분> + _ + <의미있는 테이블명> + _ + <Timing><Trigger Event><일련번호> + _ + TG

® Timing : B(Before), A(After)

® Trigger Event : I(Insert), D(Delete), U(Update)

 

) I01_MASTER_TB 테이블에서 데이타 입력 후에 실행되는 Trigger

: I01_MASTER_AU01_TG

 

차.  View Name

1)   규칙

    길이는 제한이 없으며, 영문 대문자로 작성함

    해당하는 테이블명의  뒤에 _VW라는 구분을 사용함

    일련번호는 01 ~ 99까지 사용할  있음

 

2)   표기방식

<시스템 구분> + _ + <의미있는 테이블명><일련번호> + _ + VW

) AC_ADMINL_USER_VW

 

카.  Sequence Name <오라클의 경우에만 해당>

1)   규칙

    길이는 제한이 없으며 영문 대문자를 사용함

    해당하는 테이블명의  뒤에 _SQ라는 구분을 사용함

 

2)   표기방식

<시스템 구분> + _ + <의미있는 테이블명> + _ + SQ

) I01_MASTER_TB 테이블의 Sequence : I01_MASTER_SQ

 

타.  Package Name<오라클의 경우에만 해당>

1)   규칙

    길이는 제한이 없으며 영문 대문자를 사용함

    해당하는 테이블명의  뒤에 _PKG라는 구분을 사용함

 

2)   표기방식

<시스템 구분> + _ + <의미있는 패키지명> + _ + PKG

) 검색엔진에서 사용하는 자원에 관련된 패키지 : SCH__PKG

 

파.  Check 제약조건

1)   규칙

    길이는 제한이 없으며 영문 대문자를 사용함

    기존의 명칭룰에 해당하는 접미사를 사용하지 않고, 예외적으로 접두어 CK_ 사용한다. 일반적으로 CHECK DEFAULT 제약조건은 특정 테이블에 한정시켜서 작성하기 보다는 시스템 전반에 걸쳐서 사용이 가능하므로 예외규정을 둔다.

 

2)   표기방식

CK + _ + <의미있는 CHECK>

) 이메일 체크 : CK_EMAIL

) 성별 체크 : CK_SEX

 

하.  Default 제약조건

1)   규칙

    길이는 제한이 없으며 영문 대문자를 사용함

    기존의 명칭룰에 해당하는 접미사를 사용하지 않고, 예외적으로 접두어 DF_ 사용한다. 일반적으로 CHECK DEFAULT 제약조건은 특정 테이블에 한정시켜서 작성하기 보다는 시스템 전반에 걸쳐서 사용이 가능하므로 예외규정을 둔다

 

2)   표기방식

DF + _ + <의미있는 DEFAULT>

) Null String Default  DF_NULLSTR
) 0(Zero) Default  DF_ZERO

 

경우에 따라 (계좌번호,휴대폰) 부분 마스킹 처리가 필요하여 정규식 패턴 몇 가지 정리 하려고 한다. (업데이트 중..)

Regex Test https://regex101.com/

 

regex101: build, test, and debug regex

Regular expression tester with syntax highlighting, explanation, cheat sheet for PHP/PCRE, Python, GO, JavaScript, Java. Features a regex quiz & library.

regex101.com

samplecode

using System;
using System.Text.RegularExpressions;	
public class Program
{
        static void Main(string[] args)
        {
            string[] input = new[] {
            "123-00-0012-349",
            "1234-1234-1234-1234",
            "010-8888-9999"
            };
            string[] pattern = new[] {
	// 1234-1234-1234-1234 패턴
	@"((?<=\d{4}[ -]\d{4}[ -]\d{2})\d{2})|(?<=\d{4}[ -]\d{4}[ -]\d{4}[ -])\d{4}",
	// 123-00-0012-349  패턴
	@"((?<=\d{3}[ -]\d{2}[ -]\d{2})\d{2})|((?<=\d{3}[ -]\d{2}[ -]\d{4}[ -])\d{2})",
	// 010-8888-9999  패턴
	@"\d{4}(?!\d{0,4}$)"
            };
            string replacement = string.Empty;


            for (int i = 0; input.Length > i; i++)
            {
                for (int k = 0; pattern.Length > k; k++)
                {
                    if (Regex.IsMatch(input[i], pattern[k]) == true)
                    {
                        replacement = Regex.Replace(input[i], pattern[k], new MatchEvaluator(math => new string('*', math.Length)));
                        Console.WriteLine(replacement);
                        break;
                    }
                }
            }
	}
}

output

123-00-00**-**9
1234-1234-12**-****
010-****-9999

'C#' 카테고리의 다른 글

C# Single or array JSON converter.  (0) 2021.10.07
C# Task WaitAll 와 WhenAll  (0) 2021.09.16
c# Entity Framework  (0) 2021.08.29
[C#] Garbage Collection  (0) 2021.07.08
세가지 Timer 객체의 차이점 (간략메모,참조 링크 포함)  (0) 2021.05.21

1. 디비 서버 유저 조회 쿼리

select * from sys.server_principals;


2. 특정 유저 로그인 정보 조회 쿼리

sp_helplogins [loginID] ;


2–1. 특정 유저 로그인 정보 변경

alter login [loginID] with password=’password’ unlock
                     ,check_policy=off
                     ,check_expiration=off
                     ,default_database=[dbname]
                     ,name=[newloginID];


check_policy = sql server 윈도우 비밀번호 정책 사용여부
check_expiration = sql server 비밀번호 만료 정책 적용 여부
default_database = DB 로그인 시 할당할 기본 데이터베이스 지정
name = 로그인ID 변경
unlock = 잠금해체


3. DB 소유자 조회 쿼리

select 	  owner_sid, suser_sname(owner_sid) ‘owner name’, physical_database_name 
 from 	  sys.databases where name= [dbname];

3–1. DB 권한 수정- db 소유자 변경

sp_changedbowner ‘loginID’

4. DB 역할 조회

select * 
from sys.database_principals;

select name
      ,default_schema_name
      ,owning_principal_id
      ,create_date
      ,authentication_type
      ,authentication_type_desc 
from   sys.database_principals;

5. 접속한 데이터베이스 스키마 조회

select * from sys.schemas;

6. 특정유저 특정 스키마 권한 부여

grant select, excute, insert, update, view definition on schema::[schema] to [loginID];


7. 리눅스에서 sql 파일 실행 시 터미널 열어서 sql파일 위치 폴더 경로 이동 후

sqlcmd -S 192.168.0.0 -i data.sql -o log.text -U loginID -P password -d dbName


-S = 서버 ip
-i = 파일명
-o = 실행결과 로그파일
-U = 유저ID
-d = 데이터베이스명

- Entity Framework에서 Code-First로 Model을 생성하는 것에 대한

- Code-First Model에서 다른 Table과의 관계에 대한

 

  내용을 간단히 남기고자 한다

 

위로 개념을 올린 김에 ORM 을 보자

C#과 같은 객체 지향형 프로그래밍 언어에서 데이터베이스를 쉽게 사용하기 위한 도구라고 한 줄로 말할 수 있다

OOP개념의 객체(Object)와 관계(Relation)형 DB의 테이블을 맵핑(Mapping)해서 (native)SQL 작성을 안하고 쉽게 DB의 데이터에 Access 할 수 있는 기술이라고도 할 수 있다

여기서 나오는 3개의 단어 Object / Relation / Mapping 이 것이 ORM에서 쓰는 핵심 단어이다. ASP.NET 에서는 데이터 엑세스하는 기본 프레임워크로 Entity Framework를 쓰기 때문에 기본값 처럼 사용하는 것이다.

 

Entity Framwork 모델

크게 3가지가 있다고 한다

1. Code First

2. Model First

3. Database First   

Model First와 Database First 접근 모델은 Visual Studio 의 Visual Model Designer (EDMX) 를 통해 객체/테이블 매핑을 디자인 하는 방식으로 두 개간 차이점은 Database Frist는 기존 DB로 부터 테이블 구조를 읽어와서 디자이너를 통해 Visual Model로 구성되는 것을 말하고 Model First는 기존 DB가 없을 때 직접 Model Designer를 써서 Entity들을 추가해 가면서 모델을 구성하는 방식이다. 위 두가지는 Visual Model Designer로 디자인한 것을 edmx 파일에 저장하게 된다.

Code First 방식은 Model Designer / EDMX를 사용하지 않고 데이터 모델을 C# 클래스로 직접 코딩하는 방식으로 앞으로의 EF는 Code First 방식만을 지원한다고 한다. (http://www.csharpstudy.com/web/article/8-Entity-Framework)

 

Code First

C# 클래스로 테이블의 구조를 정의하고 클래스의 프로퍼티를 테이블 컬럼으로 맵핑한다.

Code First란 말 그대로 DB를 미리 설계하지 않고 C# 클래스로 Domain Object(Model???) 를 정의하고 프로그램 실행 시 DB가 없으면 자동으로 DB를 생성하는 방식을 취한다

-> 이 말은 코드 우선이니까 테이블 모델이 Code 기반에서 생성되고 DB에 대한 생성과 추가 수정이 Code 기반의 Class Model에서 된 다는 것을 말한다

     MS SQL의 management studio를 통해 추가/수정/설정을 하는 것이 아니라 code로 구현해서 DB 관리자가 설정하는 것 처럼 추가하고 변경 사항을

    할 수 있다는 것을 말한다

 

재밌는 부분은 Table 과 맵핑되는([Table("name")] 이런 형태의 단순한 Entity Class를 POCO(Plain Old CLR Obect) 라고 부른다고 한다. 기본적인 단순히 테이터를 저장하고 담아저 전달되는 모델을 말하는데 자바에서는 POJO라는 것이 있었다 (Plain Old Java Object) 두 개가 같은 개념으로 보인다. 제일 기본이 되는 Model 객체?? (비즈니스가 딱히 없는??) 이라고 생각하면 쉬울 것 같다

 

Code First를 활용하는 부분을 보다보면 크게 3가지가 나온다

1. DbContext

2. Fluent API

3. Data Annotation

위 내용을 깊게 들어가면 EF로 DB Table 추가하고 컬럼 변경 및 키지정 관계 지정 까지 프레임워크 사용법 까지 다루게 되어서 저런게 있다는 것만 간략히 말한다. DbContenxt는 간단히 System.Data.Entity의 클래스 이며 DB와 관련된 여러 API를 사용할 수 있다 Context란 말에서 뭔가 저장소Repository 란 단어가 생각나는데 Domain Classes 와 Database의 중간에 있는 녀석으로 생각하면 될 것 같다 간단히 그림으로

 

http://www.entityframeworktutorial.net/entityframework6/dbcontext.aspx 참고하자

 

DbContext가 DB 전체를 관리할 수 있는 API를 제공하는 느낌이라면 Fluent API는 Table에 대한 설정을 할 수있다 테이블 간의 관계나 키 설정과 관련된 매서드들을 사용할 수 있다 Data Annotation은 C#의 Attribute로 컬럼의 값에 대한 Data Validation이나 컬럼의 속성(기본키(Key, notMapped))에 대해 프로터티 바로 위에 지정할 수 있다

즉 DB 제어 / Table 제어 같은 것이지 않겠나

 

마지막으로

Code-First Model에서 다른 Table과의 관계에 대한 표현은 크게 3가지가 있다

1. 1:1 관계

2. 1:N 관계

3. N:M 관계

아마도 관계형 데이터베이스라는 개념에서 관계라는 것이 핵심일 듯 하다 이놈의 관계에서 정규화도 고려되고 인덱스 키나 Join 할 테이블도 고려된다 그냥 테이블 간의 관계라고만 생각하기보다는 Object 간의 연관된 관계로 생각해야 그 객체 안의 속성이 어떤 특성이며 이 특성은 어떤 요소들의 집합 모임인지까지 생각할 수 있을 것 같다

(수학에서 집합/확률통계/방정식(변수를 통한 식만들기) 는 체감적으로 많이 나오는 것 같다 (선형대수학이나 행렬은 아직 뭔가 더 해봐야 알 것 같다)

 

관계는 코드로 보는게 편하다

(https://www.c-sharpcorner.com/UploadFile/3d39b4/relationship-in-entity-framework-using-code-first-approach-w/)

 

일대일 관계

namespace Tester.Data  
{  
   public class User : BaseEntity  
    {  
        public string UserName { get; set; }  
        public string Email { get; set; }  
        public string Password { get; set; }  
        public UserProfile UserProfile { get; set; }  
    }  
}
namespace Tester.Data  
{  
   public class UserProfile : BaseEntity   
    {  
        public string FirstName { get; set; }  
        public string LastName { get; set; }  
        public string Address { get; set; }  
        public virtual User User { get; set; }  
    }  
}

 

두 클래스간 virtual 속성으로 각각의 class 간 연결을 만들었다 즉 연결되어 있는 다른 테이블의 속성을 알 수 있다

using System.Collections.Generic;  
  
namespace Tester.Data  
{  
  public  class Customer : BaseEntity   
    {  
      public string Name { get; set; }  
      public string Email { get; set; }  
      public virtual ICollection<Order> Orders { get; set; }  
    }
using System;  
  
namespace Tester.Data  
{  
    public class Order : BaseEntity  
    {  
        public byte Quanatity { get; set; }  
        public Decimal Price { get; set; }  
        public Int64 CustomerId { get; set; }  
        public virtual Customer Customer { get; set; }  
    }  
}

 

virtual로 선언된 객체를 보면 한쪽이 Collection이다 Code First로 생성한 Entity는 HashSet(ICollection 상속된 클래스)으로 자료형이 되어 있는데 어쨌든 .Net 적으로 얘기하면 Collection 객체를 포함하고 있다는 것이다. 그러니 단순 List도 포함된다

하나의 객체가 다수의 다른 객체를 가지고 있으니 1:N 관계가 성립되는 것이고 부모하나에서 파생된 자식들이라고도 표현이 되고 Has 관계로 연관된 Object / Entity / Table 라는 개념을 포함할 수 있다

(OOP는 진짜 용어들만 이해해도... (개념적/논리적/물리적) 이런 구분인건가? 누군가에게 설명하기도 어렵고 하고 싶지 않는 부분이다...  

어쨌든 일대다 관계는 하나의 객체가 다수의 객체를 포함한다.. 이렇게 정의할 수 있다

 

다대다 관계

using System.Collections.Generic;  
  
namespace Tester.Data  
{  
    public class Student : BaseEntity  
    {  
        public string Name { get; set; }  
        public byte Age { get; set; }  
        public bool IsCurrent { get; set; }  
        public virtual ICollection<Course> Courses { get; set; }  
    }  
}  


using System;  
using System.Collections.Generic;  
  
namespace Tester.Data  
{  
   public class Course : BaseEntity  
    {  
       public string Name { get; set; }  
       public Int64 MaximumStrength { get; set; }  
       public virtual ICollection<Student> Students { get; set; }  
    }  
}

위의 일대다를 보고 다대다를 보면 매우 간단히 답이 나온다 각각 서로에 대한 Collection 객체를 가지고 있으면 다대다 관계이다.

여기서 포인트랄 하나 잡자면 다대대 관계를 그대로 쓰지 않는다 두개 간의 관계를 연결해주는 연결테이블 or 맵핑테이블 or 조인테이블 이런 단어로 사용되는 테이블이 가운데 있다 간단히 생각하면 다대다 관계를 다이렉트로 연결하는 것이 아니라 중간에 맵핑테이블을 두어서 일대다 관계 두 개로 쪼개는 것이다. 그러면 EF의 Database First에서 EDMX 파일에서는 맵핑 Class가 생기고 그 맵핑 정보를 각각 가지고 있는다 위의 코드는 관계만 정의된 것이고 맵핑 Entity에 대한 포함 객체는 없는 것이다. 여기서 DB의 관계와 객체인 Class간에 차이가 생길 수 있는데 (회사 업무에서 발견)

간단히 생각하면 객체에 대한 역정규화 기법?? 이라고 보인다

 

맵핑 객체를 EF가 만들어 준대로 바로 쓰는 것이 아니라 Business Model로 변경 시 해당 컬럼을 프로퍼티의 일부로 포함 할 수도 있고 이미 관계테이블에 포함한 프로퍼티일 경우 중복된 프로퍼티(컬럼)을 쓰지 않아도 되는 것이다.

물론 Entity 형태의 Model을 그대로 쓰는 것이 아니라 모델이 Customizing 되기 때문에 모델이 합쳐지거나 Colection이 포함되는 관계를 맺을 때 중복된 data를 제거하거나 1:N 으로 변경된 Class 내부에 포함하거나 해서 다른 class의 속성을 가져 올 수 있는 것이다.

 

DB에서 중복을 만들거나 두 개의 Entity를 합치는 경우 보통 역정규화라고 하는 것 처럼

Class에서도 맵핑 Class를 포함 하거나 Class를 해체해서 관련 Class의 프로퍼티로 포함 시키는 부분이 모델의 역정규화 인 것 처럼 보인다.

물론 Business Model / Customizing Model에서 쓰이는 부분이다.

 

예제로 만들면 좋겠지만... 개념적인 부분에 시간이 너무 들어가서 말로 압축한다.. 길어야 하루면 될게 몇시간 초과되었다...

기본 개념은 1:N 관계 2개의 Class가 생기고 그 Mapping Entity도 Class로 생성이 되나 Business Model을 만들면서 중복을 합치거나 Class를 해체해서 관계 Class에서 자기 속성으로 바로 접근하게 만드는 건 그때그때 다르다고 생각하면 된다. 

기술 블로그

Netfilx  https://netflixtechblog.com/
Naver D2 https://d2.naver.com/news
kakao  https://tech.kakao.com/blog/
Line  https://engineering.linecorp.com/en/blog/
ZUM  https://zuminternet.github.io/
우아한 형제들 http://woowabros.github.io/
Popit  https://www.popit.kr/
vcnc 기술블로그 http://engineering.vcnc.co.kr/
개발자스럽다  https://blog.gaerae.com/
이상한 모임 https://blog.weirdx.io/
어썸데브 블로그 메일링으로 구독  http://daily-devblog.com/

+ Recent posts