JavaRush /Java Blog /Random-KO /2부. DBMS 구조, 테이블 및 데이터 유형
Marat Sadykov
레벨 41

2부. DBMS 구조, 테이블 및 데이터 유형

Random-KO 그룹에 게시되었습니다
첫 번째 부분
2부. DBMS 구조, 테이블 및 데이터 유형 - 1
우리는 계속해서 간단한 증권 거래소 에뮬레이터를 만듭니다. 우리가 할 일은 다음과 같습니다:
  • 데이터베이스 구성 다이어그램을 만들어 보겠습니다.
  • 무엇을, 어떻게, 어디에 저장하는지 설명하겠습니다.
  • 데이터가 서로 어떻게 연관되어 있는지 알아봅시다.
  • SQL 테이블 생성 명령어인 CREATE TABLE , SQL 언어의 DDL (Data Definition Language) 예시를 통해 SQL의 기본을 배워보자 .
  • 계속해서 Java 프로그램을 작성해 보겠습니다. 우리는 JDBC와 3계층 아키텍처를 사용하여 프로그래밍 방식으로 데이터베이스를 생성하기 위해 java.sql 측면에서 DBMS의 주요 기능을 구현합니다.
이 두 부분은 SQL의 기본과 DBMS 구성을 내부에서 숙지하고 Java와 비유를 이끌어 내야하기 때문에 더 방대한 것으로 나타났습니다. 코드 목록으로 지루해지지 않도록 마지막에는 프로그램과 함께 해당 커밋 github 저장소에 대한 링크가 있습니다.

DBMS 설계

애플리케이션 설명

데이터 저장 구성이 프로그래밍의 필수적인 부분이라는 것을 이미 들어보셨을 것입니다. 우리 애플리케이션의 목적은 가장 간단한 교환 에뮬레이션이라는 점을 상기시켜 드리겠습니다.
  • 주어진 규칙에 따라 거래일 동안 가치가 변할 수 있는 주식이 있습니다.
  • 초기 자본을 가진 거래자가 있습니다.
  • 거래자는 자신의 알고리즘에 따라 주식을 사고 팔 수 있습니다.
교환은 고정된 시간(우리의 경우 1분) 단위 로 작동합니다. 틱 동안 주가는 변할 수 있으며, 거래자는 주식을 사고 팔 수 있습니다.

에뮬레이션 데이터 구조 교환

개별 교환 엔터티 모델을 호출해 보겠습니다. 반올림 오류를 방지하기 위해 클래스를 통해 재정 금액을 다루겠습니다 BigDecimal(자세한 내용은 기사 끝 부분의 링크에서 확인할 수 있습니다). 각 모델의 구조를 더 자세히 설명하겠습니다. 프로모션:
기인하다 유형 설명
name 정렬 이름
changeProbability 정수 각 틱의 백분율로 표시된 비율 변경 확률
startPrice BigDecimal 초기비용
delta 정수 현재 값이 변경될 수 있는 최대 비율(%)
주가:
기인하다 유형 설명
operDate 현지 날짜시간 속도 설정 시간(틱)
share 홍보 프로모션 바로가기
rate BigDecimal 주가
상인:
기인하다 유형 설명
name 속도 설정 시간(틱)
sfreqTick 정수 거래 빈도. 거래자가 작업을 수행한 후 기간(틱)으로 지정됩니다.
cash BigDecimal 주식 이외의 금액
traidingMethod 정수 거래자가 사용하는 알고리즘. 이를 상수로 설정해 보겠습니다. 알고리즘의 구현은 (다음 부분에서) Java 코드로 이루어집니다.
changeProbability 정수 작업 완료 확률, 백분율
about 각 틱의 비율 변화 확률(%)
상인의 행동:
기인하다 유형 설명
operation 정수 거래 유형(구매 또는 판매)
traider 상인 트레이더 링크
shareRate 주가 주가에 대한 링크(각각 주식 자체, 주가, 발행 시기)
amount 거래에 참여한 주식 수
각 모델의 고유성을 보장하기 위해 longid 유형의 속성을 추가합니다 . 이 속성은 모델 인스턴스 내에서 고유 하며 이를 고유하게 식별합니다. 다른 모델(거래자, 주식, 주가)을 참조하는 속성은 이 속성을 사용하여 해당 모델을 고유하게 식별할 수 있습니다. 해당 모델이 어디에 있는지, 그러한 데이터를 저장하는 데 사용할 수 있다는 생각이 즉시 떠오릅니다 . 그러나 다음 조건에서 코드에서 이를 구현해 보세요. idMap<Long, Object>Object
  • 데이터 크기가 사용 가능한 RAM 용량을 크게 초과합니다.
  • 데이터에 대한 액세스는 12개의 다른 장소에서 예상됩니다.
  • 데이터를 수정하고 읽는 기능이 동시에 필요합니다.
  • 데이터의 형성과 무결성을 위한 규칙을 보장하는 것이 필요합니다.
...그리고 적절한 자격과 구현 시간이 필요한 작업에 직면하게 될 것입니다. "바퀴를 재발명"할 필요는 없습니다. 우리를 위해 이미 많은 것이 고려되고 작성되었습니다. 따라서 우리는 수년에 걸쳐 이미 테스트된 것을 사용할 것입니다.

Java에 데이터 저장

행동을 고려해 봅시다. Java에서는 , , , 필드 가 Share있는 이 모델에 대한 특정 클래스를 만들었습니다 . 그리고 많은 공유가 로 저장되었습니다 . 여기서 키는 각 공유의 고유 식별자입니다. namechangeProbabilitystartPricedeltaMap<Long, Share>
public class Share {
    private String name;
    private BigDecimal startPrice;
    private int changeProbability;
    private int delta;
}
Map<Long, Share> shares = new HashMap<>();
shares.put(1L, new Share("ibm", BigDecimal.valueOf(20.0), 15, 10));
shares.put(2L, new Share("apple", BigDecimal.valueOf(14.0), 25, 15));
shares.put(3L, new Share("google", BigDecimal.valueOf(12.0), 20, 8));
...
shares.put(50L, new Share("microsoft", BigDecimal.valueOf(17.5), 10,4 ));
ID별로 원하는 프로모션에 접근하려면 메소드를 사용하세요 shares.get(id). 이름이나 가격으로 주식을 찾는 작업을 위해 필요한 것을 찾는 모든 레코드를 반복합니다. 하지만 우리는 다른 방법으로 DBMS에 값을 저장하겠습니다.

DBMS에 데이터 저장

DBMS에 대한 초기 데이터 저장 규칙 세트를 공식화해 보겠습니다.
  • DBMS의 데이터는 레코드 집합인 테이블( TABLE )로 구성됩니다.
  • 모든 레코드에는 동일한 필드 집합이 있습니다. 테이블을 생성할 때 설정됩니다.
  • 필드는 기본값( DEFAULT )으로 설정할 수 있습니다.
  • 테이블의 경우 무결성을 보장하기 위해 데이터에 대한 요구 사항을 설명하는 제약 조건( CONSTRAINT )을 설정할 수 있습니다. 이는 테이블 생성 단계( CREATE TABLE )에서 수행하거나 나중에 추가( ALTER TABLE ... ADD CONSTRAINT )할 수 있습니다.
  • 가장 일반적인 CONSTRAINT :
    • 기본 키는 PRIMARY(여기서는 Id)입니다.
    • 고유 값 필드 UNIQUE (차량 테이블의 경우 VIN).
    • CHECK 필드를 확인하는 중입니다 (백분율 값은 100보다 클 수 없습니다). 필드에 대한 비공개 제한 사항 중 하나는 NOT NULL 또는 NULL 입니다 . 이는 테이블 필드에 NULL 저장을 금지/허용합니다.
    • 타사 테이블 FOREIGN KEY 에 대한 링크 (주가 테이블의 주식에 대한 링크)
    • Index INDEX (필드를 인덱싱하여 값 검색 속도를 높임)
    • 해당 필드의 값이 제한 사항(CONSTRAINT)과 모순되는 경우 레코드 수정( INSERT , UPDATE )이 발생하지 않습니다.
  • 각 테이블에는 레코드를 고유하게 식별하는 데 사용할 수 있는 키 필드(또는 여러 개)가 있을 수 있습니다. 이러한 필드(복합 키를 형성하는 경우 필드)는 테이블의 기본 키( PRIMARY KEY ) 를 형성합니다 .
    • 기본 키는 테이블 내 레코드의 고유성을 보장하며, 여기에 인덱스가 생성되어 키 값을 기반으로 전체 레코드에 빠르게 액세스할 수 있습니다.
    • 기본 키가 있으면 테이블 간의 링크를 훨씬 쉽게 만들 수 있습니다. 다음으로 인공 기본 키를 사용합니다. 첫 번째 레코드의 경우 id = 1각 후속 레코드는 id 값이 1씩 증가하여 테이블에 삽입됩니다. 이 키는 AutoIncrement 또는 AutoIdentity 라고도 합니다 .
실제로 주식 테이블: 2부. DBMS 구조, 테이블 및 데이터 유형 - 2 이 경우 주식 이름을 키로 사용할 수 있습니까? 대체로 그렇습니다. 그러나 일부 회사는 다른 주식을 발행하고 자체 이름으로 만 부를 가능성이 있습니다. 이 경우 고유성은 더 이상 존재하지 않습니다. 실제로는 인공적인 기본 키가 자주 사용됩니다. 사람의 기록이 포함된 테이블에서 전체 이름을 고유 키로 사용하면 고유성이 보장되지 않는다는 점에 동의하세요. 이름과 생년월일을 조합하여 사용하는 것도 가능합니다.

DBMS의 데이터 유형

다른 프로그래밍 언어와 마찬가지로 SQL에도 데이터 입력 기능이 있습니다. 가장 일반적인 SQL 데이터 유형은 다음과 같습니다. 정수 유형
SQL 유형 SQL 동의어 Java에서 일치 설명
정수 INT4,정수 java.lang.정수 4바이트 정수, -2147483648 ~ 2147483647
부울 부울, 비트 java.lang.Boolean 허위 사실
TINYINT java.lang.Byte 1바이트 정수, -128 ~ 127
스몰린트 INT2 java.lang.Short 2바이트 정수, -32768 ~ 32767
빅트 INT8 java.lang.Long 8바이트 정수, -9223372036854775808 … 9223372036854775807
자동 증가 증가 java.lang.Long 테이블에 고유한 증분 카운터입니다. 새로운 값이 삽입되면 1씩 증가하며, 생성된 값은 절대 반복되지 않습니다.
진짜
SQL 유형 SQL 동의어 Java에서 일치 설명
십진수(N,M) 12월, NUMBER java.math.BigDecimal 고정 정밀도 십진수(N 정수 자리 및 M 분수 자리). 주로 재무 데이터 작업을 위해 설계되었습니다.
더블 FLOAT8 java.lang.Double 배정밀도 실수(8바이트)입니다.
진짜 플로트4 java.lang.실제 단정밀도 실수(4바이트)입니다.
SQL 유형 SQL 동의어 Java에서 일치 설명
VARCHAR(N) NVARCHAR java.lang.문자열 길이가 N인 UNICODE 문자열. 길이는 2147483647로 제한됩니다. 문자열의 전체 내용을 메모리에 로드합니다.
날짜와 시간
SQL 유형 SQL 동의어 Java에서 일치 설명
시간 java.time.LocalTime, java.sql.Time 저장시간(최대 나노초)을 DATETIME으로 변환하면 날짜가 1970년 1월 1일로 설정된다.
날짜 java.time.LocalDate, java.sql.Timestamp yyyy-mm-dd 형식으로 날짜를 저장하며 시간은 00:00으로 설정됩니다.
날짜 시간 타임스탬프 java.time.LocalDateTime, java.sql.Timestamp 날짜 + 시간 저장(시간대를 고려하지 않음)
대용량 데이터 저장
SQL 유형 Java에서 일치 설명
얼룩 java.io.InputStream, java.sql.Blob 바이너리 데이터(사진, 파일...) 저장.
클로브 java.io.Reader, java.sql.Clob 대용량 텍스트 데이터(책, 기사...)를 저장하면 VARCHAR과 달리 데이터를 부분적으로 메모리에 로드합니다.

SQL 작성 스타일

많은 언어에는 코드 형식 지정 지침이 있습니다. 일반적으로 이러한 문서에는 변수, 상수, 메서드 및 기타 언어 구조의 이름을 지정하는 규칙이 포함되어 있습니다. 따라서 Python의 경우 Java용 PEP8 - Oracle Code Conventions for Java 가 있습니다 . SQL에 대해 서로 약간 다른 여러 세트가 생성되었습니다. 그럼에도 불구하고, 특히 팀으로 작업하는 경우 코드 형식을 지정할 때 규칙을 따르는 습관을 길러야 합니다. 예를 들어 규칙은 다음과 같을 수 있습니다. (물론 스스로 다른 규칙 세트를 개발할 수도 있습니다. 가장 중요한 것은 앞으로 이 규칙을 고수하는 것입니다.)
  • 명령, 연산자를 포함한 키워드와 예약어는 대문자로 작성해야 합니다(CREATE TABLE, CONSTRAINT...).
  • 테이블, 필드 및 기타 개체의 이름은 SQL 언어 키워드와 일치해서는 안 되지만(문서 마지막에 있는 링크 참조) 이를 포함할 수 있습니다.
  • 테이블 이름은 해당 목적을 반영해야 합니다. 소문자로 작성됩니다. 이름의 단어는 밑줄로 서로 구분됩니다. 끝에 있는 단어는 복수형 이어야 합니다 : traders(traders), share_rates(share rate).
  • 테이블 필드 이름은 해당 목적을 반영해야 합니다. 소문자로 작성해야 하며, 이름에 있는 단어는 Camel Case 스타일로 작성해야 하며, 끝에 오는 단어는 단수형 (name(이름), share_rates(주율)) 으로 사용해야 합니다 .
  • 인공 키 필드에는 ID라는 단어가 포함되어야 합니다.
  • CONSTRAINT 이름은 테이블 명명 규칙을 따라야 합니다. 또한 관련 필드와 테이블도 포함해야 하며 의미 접두사인 check_(필드 값 확인), pk_(기본 키), fk_(외부 키), uniq_(필드 고유성), idx_(인덱스)로 시작해야 합니다. 예: pk_traider_share_actions_id(trader_share_actions 테이블의 id 필드에 대한 기본 키)
  • 그리고 SQL을 공부하면서 규칙 목록이 보충/변경됩니다.

DBMS 설계

DBMS를 만들기 직전에 설계가 필요합니다. 최종 스키마에는 테이블, 필드 세트, CONSTRAINT, 키, 필드의 기본 조건, 테이블과 기타 데이터베이스 엔터티 간의 관계가 포함됩니다. 인터넷에서는 소규모 DBMS 설계를 위한 무료 온라인/오프라인 디자이너를 많이 찾을 수 있습니다. 검색 엔진에 "Database Designer free"와 같은 것을 입력해 보세요. 이러한 애플리케이션에는 다음과 같은 유용한 추가 속성이 있습니다.
  • DBMS를 생성하기 위한 SQL 명령을 생성할 수 있습니다.
  • 다이어그램에 설정을 시각적으로 표시합니다.
  • 더 나은 시각화를 위해 테이블을 이동할 수 있습니다.
  • 키, 인덱스, 관계, 기본값 등을 다이어그램에 표시합니다.
  • DBMS 스키마를 원격으로 저장할 수 있습니다.
예를 들어 dbdiffo.com은 키를 강조 표시하고 비어 있지 않은 필드와 NN 레이블이 있는 AI(AutoIncrement) 카운터를 표시합니다.
2부. DBMS 구조, 테이블 및 데이터 유형 - 3

DBMS에서 테이블 생성

그래서 우리는 다이어그램을 가지고 있습니다. 이제 테이블 생성(CREATE TABLE)으로 넘어가겠습니다. 이를 위해서는 예비 데이터를 확보하는 것이 좋습니다.
  • 테이블 이름
  • 필드 이름 및 유형
  • 필드에 대한 제한 사항(CONSTRAINTS)
  • 필드의 기본값(사용 가능한 경우)
  • 기본 키(PRIMARY KEY)(사용 가능한 경우)
  • 테이블 간 연결(외래 키)
CREATE TABLE 명령의 모든 옵션을 자세히 연구하지는 않고 거래자를 위한 테이블 생성 예를 사용하여 SQL의 기본 사항을 살펴보겠습니다.
CREATE TABLE traiders(
	id BIGINT AUTO_INCREMENT PRIMARY KEY,
	name VARCHAR(255) NOT NULL,
	freqTiсk INTEGER NOT NULL,
	cash  DECIMAL(15,2) NOT NULL DEFAULT 1000,
	tradingMethod INTEGER NOT NULL,
	changeProbability INTEGER NOT NULL DEFAULT 50,
	about VARCHAR(255) NULL
);
ALTER TABLE traiders ADD CONSTRAINT check_traiders_tradingMethod
	CHECK(tradingMethod IN (1,2,3));
ALTER TABLE traiders ADD CONSTRAINT check_traiders_changeProbability
	CHECK(changeProbability <= 100 AND changeProbability > 0)
자세히 살펴보겠습니다.
  • CREATE TABLE traiders(필드 설명) - 지정된 이름으로 테이블을 생성하며, 설명에서 필드는 쉼표로 구분됩니다. 모든 명령은 세미콜론으로 끝납니다.
  • 필드 설명은 해당 이름으로 시작하고 그 뒤에 해당 유형, CONSTRAINT 및 기본값이 옵니다.
  • id BIGINT AUTO_INCREMENT PRIMARY KEY– 정수 유형의 id 필드는 기본 키와 증분 카운터입니다(id 필드에 대한 각각의 새 레코드에 대해 이 테이블에 대해 이전에 생성된 값보다 1 큰 값이 생성됩니다).
  • cash DECIMAL(15,2) NOT NULL DEFAULT 1000– 현금 필드, 소수점, 소수점 앞 15자리, 뒤 2자리(금융 데이터, 예: 달러 및 센트). NULL 값을 허용할 수 없습니다. 값을 지정하지 않으면 값 1000을 가져옵니다.
  • about VARCHAR(255) NULL– 최대 255자의 문자열인 정보 필드에는 빈 값을 사용할 수 있습니다.
테이블을 생성한 후 CONSTRAINT 조건의 일부를 설정할 수 있습니다 . 테이블 구조와 해당 필드를 수정하기 위한 구성을 고려해 보겠습니다. ALTER TABLE table_name ADD CONSTRAINT Constraint_name CHECK(조건) 예를 사용하여:
  • CHECK(tradingMethod IN (1,2,3))– TradingMethod 필드에는 1,2,3 값만 사용할 수 있습니다.
  • CHECK(changeProbability <= 100 AND changeProbability > 0)–changeProbability 필드는 1에서 100 사이의 정수 값을 가질 수 있습니다.

테이블 간의 관계

테이블 간의 관계에 대한 설명을 분석하기 위해 share_rates 생성을 살펴보겠습니다.
CREATE TABLE share_rates(
	id BIGINT AUTO_INCREMENT PRIMARY KEY,
	operDate datetime NOT NULL,
	share BIGINT NOT NULL,
	rate DECIMAL(15,2) NOT NULL
);
ALTER TABLE share_rates ADD FOREIGN KEY (share) REFERENCES shares(id)
2부. DBMS 구조, 테이블 및 데이터 유형 - 4
다른 테이블의 값에 대한 참조는 다음과 같이 설정할 수 있습니다. ALTER TABLEtable_from_which_referred ADD FOREIGN KEY(field_that_referred) REFERENCEStable_to_which_referred( field_that_referred ) 17.5, 델타는 20, 변경 가능성은 4%입니다. share_rates 테이블 의 경우 세 가지 주요 속성을 얻습니다.
  • 공유 테이블에서 나머지 정보(이름 등)를 얻는 데 사용하려면 공유 테이블의 id 키 값만 공유 필드에 저장하면 됩니다.
  • 존재하지 않는 프로모션에 대해서는 요금을 생성할 수 없습니다. 테이블 간에 대응이 없기 때문에 존재하지 않는 값을 공유 필드(이 ID를 가진 공유 테이블에 레코드가 없음)에 삽입할 수 없습니다.
  • share_rates에 요율이 설정된 주식에서는 주식 항목을 삭제할 수 없습니다.
마지막 두 지점은 저장된 데이터의 무결성을 보장하는 역할을 합니다. 기사 끝 부분에 있는 github 저장소 링크를 사용하여 해당 클래스의 Java 메소드 구현에서 에뮬레이션의 SQL 테이블 생성과 SQL 쿼리의 예를 볼 수 있습니다. 세 번째 부분
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION