- 로컬에서 어떤 파일을 저장했을 때, 다른 컴퓨터에서 저장한 파일을 불러올 수 없기 때문에, 데이터베이스를 이용해서 언제 어디서든지 데이터를 불러올 수 있다. ->SaveFile
- SQLServer 프로그램이 있다. 이 프로그램은 서버에서 데이터를 받고 저장하기 때문에, 서버의 기능이 갖춰져 있어야 한다.
파일
- RDB로 할 수 없을 때는 파일로 저장하면 된다. -> 데이터 베이스의 기본
파일 > DBMS : 저장 및 로딩 속도
- 속도는 파일 저장이 더 빠르지만 DBMS는 데이터 관리와 분석하기 위해서 사용한다. 데이터가 많고, 용량이 많아지거나, 하드 관리가 힘들어질 때가 있는데 그 때는 파일 저장보다는 DBMS로 관리하는 것이 좋다.
- DBMS도 결국 파일 시스템을 사용한다.
파일 X 데이터 베이스 O - 데이터 백업 및 복원 기능
- 백업 서버에 데이터를 날리면 바로 저장하고,데이터베이스의 로그파일을 남겨서 복원할 수도 있다. => 백업본은 항상 남겨둬야 한다. 없으면 서비스를 닫아야 할 수도
MS SQL Server - RDB 많이 사용 많이 사용
- Oracle MySQL - RDB 많이 사용
- 데이터 베이스
GameDB라는 인스턴스
- 테이블 생성
- 행 ( 레코드 ) 0
- 열 (필드) 이름,변수 타입
- 데이터베이스 열의 타입
정수
소수
문자열
날짜, 시간
그 외(바이너리)- LogDB에 중요한 것은 날짜
NULL 허용 선택 시, 값을 정해야 한다. 정하지 않으면 DB입장에서 NULL를 반환하여 오류가 뜬다.

테이블 클릭

데이터 베이스 우클릭 하여 새 데이터베이스를 만들어본다.

이름은 Test







varchar(n) : 유동성 있는 문자열. 최대 길이 n의 문자열
nvarchar,nchar : n이 붙으면 유니코드
text : 길이 무제한 문자열 : 읽기/쓰기 속도가 느리다.
binary : 길이 무제한 바이너리
- 데이터 베이스를 액세스 할 때 필수적으로 알아야 하는 문법
- 실무에서 신입들에게 운영 툴이나 UI 업무를 많이 주는데, 웹 서비스를 만들때 유용한 API는 아래와 같다
- CRUD
- CREATE - 추가하기
- READ - 읽기
- 변경
- 삭제- 추가하기 ( insert)
- insert into KJ (a,b,c) into (1,2,3) (설명 : KJ 테이블에 a,b,c에 1,2,3을 넣겠다)- 질의하기 (Select)
- select a,b,c from KJ where condition (설명 : KJ테이블에서 a,b,c 필드 중에 condition인 것을 조회- 갱신하기 ( Update )
- Update KJ set column = value where condition;

- 고유키 : 한 테이블에 하나만 추가, 중복 허락 X , 필드 값은 NULL 허용 X


CREATE TABLE dbo.UserAccount
(
ID INT IDENTITY(1,1) PRIMARY KEY,
Email NVARCHAR(255) NOT NULL,
[Password] NVARCHAR(255) NOT NULL,
CreatedAt DATETIME2(0) NOT NULL
CONSTRAINT DF_UserAccount_CreatedAt DEFAULT (SYSUTCDATETIME())
);
CREATE TABLE dbo.[Character]
(
ID INT IDENTITY(1,1) PRIMARY KEY,
OwnerUserAccountID INT NOT NULL,
Gender NVARCHAR(10) NULL,
[Level] INT NOT NULL
CONSTRAINT DF_Character_Level DEFAULT(1),
CreatedAt DATETIME2(0) NOT NULL
CONSTRAINT DF_Character_CreatedAt DEFAULT (SYSUTCDATETIME()),
CONSTRAINT FK_Character_UserAccount
FOREIGN KEY (OwnerUserAccountID)
REFERENCES dbo.UserAccount(ID)
ON DELETE CASCADE
ON UPDATE NO ACTION
);
CREATE TABLE dbo.Item
(
ID INT IDENTITY(1,1) PRIMARY KEY,
OwnerCharacterID INT NOT NULL,
[Type] NVARCHAR(10) NULL,
Amount INT NOT NULL
CONSTRAINT DF_Item_Amount DEFAULT(1),
CONSTRAINT FK_Item_Character
FOREIGN KEY (OwnerCharacterID)
REFERENCES dbo.[Character](ID)
ON DELETE CASCADE
ON UPDATE NO ACTION
);
GO

CREATE TABLE dbo.UserAccount // dbo 스키마에 UserAccount 테이블 생성
ID INT IDENTITY(1,1) PRIMARY KEY,
- ID는 INT // 타입
- IDENTITY(1,1) // 자동증가
- PRIMARY KEY // 기본키(중복 불가, NULL 불가)

Email NVARCHAR(255) NOT NULL,
- 최대 255자 유니코드 문자열 저장
- NOT NULL - 반드시 값이 필요
[Password] NVARCHAR(255) NOT NULL,
- 비밀번호 컬럼(예약어라 대괄호가 필요하다)

CreatedAt DATETIME2(0) NOT NULL
- 날짜/시간 저장,소수점 없는 초 단위
CONSTRAINT DF_UserAccount_CreatedAt DEFAULT (SYSUTCDATETIME())




ID INT IDENTITY(1,1) PRIMARY KEY,
- ID는 기본키이며 자동증가 된다. (1,1). 초기값 1 증가값 1
OwnerUserAccountID INT NOT NULL,
- OwnerUserAccountID는 INT 타입이로 NULL 허용하지 않는다.
Gender NVARCHAR(10) NULL,
- Gender는 유니코드 문자열 최대 10자까지 저장할 수 있고 null 허용한다.
[Level] INT NOT NULL
CONSTRAINT DF_Character_Level DEFAULT(1),
- Level은 예약어라, 대괄호로 구분
- Int타입이고, null 허용하지 않는다.
- Character 테이블에서 Level의 제약 조건은 기본값이 1이다. 캐릭터 레벨, 기본값 1.
CreatedAt DATETIME2(0) NOT NULL
CONSTRAINT DF_Character_CreatedAt DEFAULT (SYSUTCDATETIME()),
- CreatedAt는 날짜/시간을 저장하는 컬럼이고, 소수점은 없다(0). null 허용하지 않는다
- Character테이블에서 CreatedAt 컬럼 제약 조건은 값을 넣지 않으면 현재 utc 서버 시간으로 저장
CONSTRAINT FK_Character_UserAccount
FOREIGN KEY (OwnerUserAccountID)
REFERENCES dbo.UserAccount(ID)
ON DELETE CASCADE
ON UPDATE NO ACTION
- CONSTRAINT을 통해 아래 4줄을 제약 조건으로 할건데 이름을 FK_Character_UserAccount로 정함
- FOREIGN KEY (OwnerUserAccountID) - 현재 테이블의 OwnerUserAccountID 컬럼을 외래키로 설정
- REFERENCES dbo.UserAccount(ID) - 외래키(OwnerUserAccountID)는 UserAccount.ID 컬럼을 참조
- ON DELETE CASCADE - 참조중인 UserAccount의 행이 삭제되면 그 UserAcount를 참조하고 있는 Character 행도 삭제됨
- ON UPDATE NO ACTION - 부모의 기본키의 값이 변경되면 외래키의 값은 변경되지 않음.






INSERT INTO dbo.UserAccount (Email,[Password])
VALUES
('wls6189@naver.com','5532'),
('vksej1235@gmail.com','6189');
INSERT INTO dbo.[Character] (OwnerUserAccountID,Gender,[LEVEL])
VALUES
(1,'남자',5), -- ID가 1인 김진 캐릭터1
(1,'남자',4), -- ID가 1인 김진 캐릭터2
(2,'여자',3); -- ID가 2인 민솔 캐릭터1
INSERT INTO dbo.Item(OwnerCharacterID,[Type],Amount)
VALUES
(1,'Potion',10), -- ID가 1인 김진캐릭터1에게 포션 10개
(1,'Gold',500), -- ID가 1인 김진캐릭터2에게 포션 500개
(2,'Sword',1); -- ID가 2인 민솔 캐릭터1에게 포션 1개
INSERT INTO dbo.UserAccount (Email,[Password])
- dbo 스키마에 있는 UserAccount 테이블에 Email,[Passsword] 컬럼에 값을 넣을 것이라고 명시
('wls6189@naver.com','5532'), //컬럼에 맞게 문자열 입력하고 쉼표(,)를 사용하여 구분
('vksej1235@gmail.com','6189'); //컬럼에 맞게 문자열 입력하고 쉼표(,)를 사용하여 구분


INSERT INTO dbo.[Character] (OwnerUserAccountID,Gender,[LEVEL])
VALUES
(1,'남자',5), -- ID=1인 UserAccount(김진)의 캐릭터1
(1,'남자',4), -- ID=1인 UserAccount(김진)의 캐릭터2
(2,'여자',3); -- ID=2인 UserAccount(민솔)의 캐릭터1
- OwnerUserAccountID → FK. UserAccount(ID) 값을 참조해야 함.
- Gender → 성별 (남자, 여자).
- [Level] → 캐릭터 레벨.
여기서 중요한 점은 OwnerUserAccountID가 외래키로 설정하였기에 UserAccount 테이블에 ID를 참조하게 됨
ID는 따로 데이터 삽입 하지 않았다. 그 이유는 ID 컬럼을 만들 때 PK(기본키)로 설정하였고, IDENTITY(1,1)을 명시하였기에 처음에는 1부터 시작, 새 행이 삽입될 때마다 1씩 증가하게 된다.
따라서 Insert 할 때 ID 컬럼은 입력하지 않는다.
아래 조회 부분을 보면 Insert 할 때마다 ID가 1씩 증가되는 것을 볼 수 이싿.


INSERT INTO dbo.Item(OwnerCharacterID,[Type],Amount)
VALUES
(1,'Potion',10), -- ID가 1인 김진캐릭터1에게 포션 10개
(1,'Gold',500), -- ID가 1인 김진캐릭터2에게 포션 500개
(2,'Sword',1); -- ID가 2인 민솔 캐릭터1에게 포션 1개
- OwnerCharacterID → FK. Character(ID)를 참조해야 함.
- [Type] → 아이템 종류 (Potion, Gold, Sword 등).
- Amount → 아이템 수량.
여기서 중요한 점은 OwnerCharacterID가 외래키로 설정하였기에 UserAccount 테이블에 ID를 참조하게 됨
ID는 따로 데이터 삽입 하지 않았다. 그 이유는 ID 컬럼을 만들 때 PK(기본키)로 설정하였고, IDENTITY(1,1)을 명시하였기에 처음에는 1부터 시작, 새 행이 삽입될 때마다 1씩 증가하게 된다.
따라서 Insert 할 때 ID 컬럼은 입력하지 않는다.
아래 조회 부분을 보면 Insert 할 때마다 ID가 1씩 증가되는 것을 볼 수 이싿.



USE 데이터베이스이름
GO
이렇게 입력하면 존재하게 된다.
아래 코드 처럼 작성하면 조회할 수 있다.

SELECT * FROM 스키마.테이블이름 형식으로 세 테이블 모두 입력하면 세 테이블이 조회가 된다.




SELECT I.*
- dbo.Item 테이블의 모든 컬럼만 결과로 내보냄. 결과 컬럼은
- Item.ID, Item.OwnerCharacterID, Item.Type, Item.Amount
FROM dbo.UserAccount AS U
- 조회 기준 테이블을 dbo.UserAccount 로 잡고, 별칭 U로 대체
- U.ID , U.Email 처럼 짧게 참조 가능하다.
JOIN dbo.[Character] AS C
- 기본적으로 INNER JOIN(교집합)을 수행.
- 정확한 연결 방식은 다음 줄 ON 에서 정해.
- dbo.[Character] 를 별칭 C로 대체.
- C.ID,C.Gender로 처럼 짧게 참조 가능하다.
ON C.OwnerUserAccountID = U.ID
- 의미 : Join 조건. 캐릭터의 (OwnerUserAccountID)FK와 유저의 (ID)PK와 같은 행끼리 붙여라
- ON절은 테이블을 어떻게 붙일치 정의하는 자리고, 필터는 Where에서.
JOIN dbo.Item AS I
- 의미: 다시 INNER JOIN으로 지금까지 나온 행(= 유저↔캐릭터 매칭 결과)에 Item을 결합.
- 별칭 I: 이후 I.Type, I.Amount처럼 참조
ON I.OwnerCharacterID = C.ID
- 의미: 두 번째 조인 조건. 아이템의 소유 캐릭터 FK(I.OwnerCharacterID)가 캐릭터 PK(C.ID)와 같은 행만 붙여.
- 효과: 각 캐릭터가 실제로 보유한 아이템들만 결과에 남음.
- 주의(표현 보정): “캐릭터 ID와 아이템 ID 연결”이 아니라 아이템의 OwnerCharacterID와 캐릭터의 ID를 연결하는 거야.
- WHERE U.ID = 1;
- 의미: 조인된 결과에서 유저 ID가 1인 행만 남겨라.
- 타이밍(논리 처리 순서): SQL 논리적 처리 순서는 대략
- FROM → ON → (JOIN) → WHERE → SELECT → ORDER BY.
- 즉, 조인으로 붙이고 나서 그중 User=1만 필터링하는 거야.
- 결과 성질: INNER JOIN이므로, 유저 1번에게 캐릭터가 없거나 캐릭터에 아이템이 없으면 결과가 0행이 될 수 있어.
(아이템이 없어도 유저를 보고 싶다면 LEFT JOIN을 쓰면 됨.)


