스키마(Schema) Study 2011. 4. 20. 10:17

스키마(Schema)

조직 전체의 입장에서 본 DB구조로서 DB 내의 개체들에 대한 명세를 기술하며 DB를 구성하는 데이터 개체, 속성, 관계와 데이터 조작 시

데이터 값들이 갖는 제약 조건 등을 전반적으로 정의한다.

스키마는 사용자의 관점에 따라 외부 스키마, 개념 스키마, 내부 스키마로 나뉜다.

* 개체 - 파일 처리 방식의 파일에서 레코드

속성 - 필드 해당으로 개체의 성질 나타냄

관계 - 개체와 개체, 개체와 속성 간 관계

스키마의 특징

데이터 사전(Data Dictionary)에 저장

현실 세계의 특정한 한 부분의 표현으로 특정 데이터 모델을 이용해 만들어진다.

인스턴스에 의해 규정되며 데이터의 구조적 특성을 의미한다.

시간에 따라 변하지 않는다.

* 데이터 사전 = 메타데이터(Meta Data) - DB에 저장되어 있는 모든 데이터에 대한 정보를 유지, 관리하는 시스템

개념 스키마(Conceptual Schema) = 전체적 뷰

DB의 전체적인 논리적 구조로 기관의 관점에서 정의한 것이다.

개체 간의 관계, 제약조건, DB의 접근 권한, 보안, 무결성 규칙에 대한 명세를 정의한다.

DB에 저장되는 데이터의 형태이다.

데이터베이스 관리자(DBA)가 구성한다.

외부 스키마(External Schema) = 서브 스키마 = 사용자 뷰

개인의 입장에서 필요한 DB의 논리적 구조를 정의

일반 사용자는 질의어(SQL) 이용, 응용 프로그래머는 COBOL, C등의 언어를 이용해 DB에 접근할 수 있다.

같은 DB에서도 다른 관점을 정의할 수 있다.

하나의 DBS에는 여러 개의 외부 스키마가 존재 가능하며 하나를 여러 응용 프로그램, 사용자가 공유할 수 있다.

* 전체 DB의 한 논리적 일부분으로 볼 수도 있어 서브 스키마라고도 한다.

내부 스키마(Internal Scheam) = 물리적 스키마

물리적 저장장치의 입장에서 본 DB 구조로 시스템 프로그래머, 시스템 설계자의 관점이다.

DB에 저장될 레코드의 물리적인 구조 정의, 저장 데이터 항목의 표현 방법, 내부 레코드의 물리적 순서를 나타낸다.

개념적 스키마 DB의 전체적인 구조를 정의한다.

외부적 스키마DB 전체에서 일부분인 구조 내부적 스키마에 적합한 형태로 변환한다.

내부적 스키마DB의 구체적인 구조정의한다.

* DBMS외부적 스키마 따라 명시된 사용자의 요구를 개념적 스키마 적합한 형태로 변경하고 내부적 스키마 형태로 변경한다.

[출처] 스키마(Schema)|작성자 한량


'Study' 카테고리의 다른 글

관계형 DB 구조  (0) 2011.04.20
DB 설계  (0) 2011.04.20
논리적 데이터 모델  (0) 2011.04.20
데이터 모델  (0) 2011.04.20
DB 언어  (0) 2011.04.20
echo 카테고리 없음 2011. 4. 19. 11:26
echo

echo 명령

목적
문자열을 표준 출력에 기록합니다.


구문
echo [ String ... ]


설명
echo 명령은 문자열을 표준 형식으로 기록합니다. String은 공백으로 구분하며 캐리지 리턴 문자 다음에는 지정한 마지막 String 매개변수가 따라 옵니다. String 매개변수가 지정되지 않으면, 공백 행(캐리지 리턴 문자)은 표시되지 않습니다.

일반적으로 --(두 개의 하이픈)을 사용하여 하이픈으로 시작하는 문자열과 플래그를 구분할 수 있습니다. echo 명령으로 지원되는 플래그가 전혀 없는 경우, --(두 개의 하이픈)은 문자로 취급됩니다.

echo 명령은 다음과 같은 에스케이프 규정을 인식합니다.
\a 경고 문자를 표시합니다.
\b 백스페이스 문자를 표시합니다.
\c 출력에서 마지막 인수 뒤에 나오지 않는 캐리지 리턴 문자를 억제합니다. \c 배열 뒤에 오는 모든 문자는 무시됩니다.
\f 용지 넘김 문자를 표시합니다.
\n 캐리지 리턴 문자를 표시합니다.
\r 캐리지 리턴 문자를 표시합니다.
\t 탭 문자를 표시합니다.
\v 수직 탭 문자를 표시합니다.
\\ 백슬래쉬 문자를 표시합니다.
\0Number ASCII 값이 0, 1, 2 또는 3자리 8진수인 8비트 문자를 표시합니다.


주: bsh, ksh 및 csh 명령에는 각각 내장된 echo 부속 명령이 포함되어 있습니다. echo 명령과 bsh 및 ksh echo 부속 명령은 같은 방식으로 작동합니다. csh echo 부속 명령은 echo 명령과 동일한 방식으로 작동하지 않습니다. echo 부속 명령에 대한 자세한 정보는 AIX 5L 버전 5.1 시스템 사용자 안내서: 운영 시스템 및 장치의 "Bourne 쉘 내장 명령," "정규 내장 명령 설명," 및 "C 쉘 내장 명령"을 참조하십시오.
\(백슬래쉬)는 쉘에서 인용 문자입니다. 이것은 \가 ESC 문자와 함께 사용되거나 인용부호로 묶여 있는 경우(예: "\" 또는 '\'), 명령이 확장될 때 쉘이 백슬래쉬(\)를 제거하는 것을 의미합니다.

셀 확장 이후, echo 명령은 입력의 에스케이프 순서를 근거로 출력을 기록합니다. 명령의 백슬래쉬를 쉘에서 먼저 축소한 다음 echo 명령에서 축소하는 방법을 비교하는 예는 Backslash Reduction 테이블을 참조하십시오.

백슬래쉬 축소
입력된 명령 쉘 확장 이후 echo 명령의 처리 후
echo hi\\\\there echo hi\\there hi\there
echo 'hi\\\\there' echo 'hi\\\\there' hi\\there
echo "hi\\\\there' echo "hi\\there" hi\there


종료 상태
이 명령은 다음 종료 값을 리턴합니다.
0 성공적으로 완료했습니다.
>0 오류가 발생했습니다.


예제
메세지를 표준 출력에 기록하려면 다음과 같이 입력하십시오.

echo&rbl;Please&rbl;insert&rbl;diskette . . .
특수 문자를 포함하는 메세지를 표시하려면 다음과 같이 입력하십시오.

echo "\n\n\nI'm at lunch.\nI'll be back at 1:00."

이 명령은 세 개의 행을 건너뛰고 메세지를 표시합니다.

I'm at lunch.
I'll be back at 1:00.


주: 메세지에 에스케이프 순서가 포함된 경우에는 메세지를 인용부호로 묶어야 합니다. 그렇지 않으면, 쉘이 백슬래쉬 문자를 메타 문자로 해석하여 다르게 처리합니다.
패턴 대응 문자로 echo 명령을 사용하려면 다음과 같이 입력하십시오.

echo The back-up files are: *.bak

이 명령은 백업 파일 뒤에는 .bak로 끝나는 현재 디록토리에 파일 이름이 나온다는 메세지를 표시합니다.

텍스트의 한 행을 파일에 추가하려면 다음과 같이 입력하십시오.

echo Remember to set the shell search path to $PATH. >>notes

이 명령은 쉘이 PATH 쉘 변수의 값을 대체한 후에 파일의 주석 끝에 메세지를 추가합니다.

메세지를 표준 오류 출력에 기록하려면 다음과 같이 입력하십시오.

echo Error: file already exists. >&2

이 명령은 오류 메세지의 방향을 표준 오류로 재지정합니다. 만일 >&2가 생략되면 메세지가 표준 출력에 기록됩니다.


파일

/usr/bin/echo echo 명령을 포함합니다.


관련 정보

bsh 명령, csh 명령, ksh 명령, printf 명령.

[출처] echo |작성자 멋진여자



select distinct field1

from tb_test

이렇게 하면 field1에 있는 데이터 중 중복을 제거하고 유니크 한 값들만 나온다.

그러나 시간 개념이 들어가서 최신의 데이터에 해당하는 row의 값을 다 가져 오고 싶다면?

distinct에 시간까지 걸면 모든 데이터가 다 유니크 해버린다.

oracle db 데이터 중 특정 필드의 중복을 제거하고 최신의 데이터 1개만 가져오기.

숨어 있던 rowid가 이때 도움을 준다.


select *

from tb_test

where reg_tm between start_tm and end_tm

and rowid in (select max(rowid) from tb_test group by field1)


중복이 되면 안되는 필드를 group by 해서 rowid를 큰 것 순으로 뽑아내면 된다.

...라고 썼는데, 생각해보니.. scan 범위를 더 줄일 수 있을 것 같다.

물론 이건 환경과 쓰는 사람 마음에 따라 다르다. 내가 찾은 예제에선 저렇게 되어 있었고..

나는 시간 범위 내에서 중복된 값 중 최신의 것만 찾아내면 되니까.


select *

from tb_test

where rowid in (select max(rowid) from tb_test where reg_tm between start_tm and end_tm group by field1)


요렇게 작성하면 스캔 범위가 줄어들어 위의 쿼리보단 성능향상에 도움이 될 수 있을 것 같다.

이 구문은 rowid가 숫자일 경우에만 유효합니다.

'먹고살기 > Oracle' 카테고리의 다른 글

오라클(oracle) 아카이브모드  (0) 2011.04.22
오라클함수 TO_CHAR (datetime)  (0) 2011.04.22
ORACLE GROUP BY와 함께 쓰이는 HAVING 절  (0) 2011.04.06
select구문  (0) 2011.04.06
오라클 유저 생성  (0) 2011.04.05
HAVING 절은 GROUP BY 절에 의해 나오는 나올수 있는 결과에 대해 filtering 해주는 역활을 해준다.
즉 내가 지금까지 생각하던 거와는 달리
group 함수의 결과 컬럼에 대해서만 조건을 주는 게 아니라
결과 SET group by 절에 의해 나올 수 있는 결과 set 에 대해 조건을 줄 수 있다.

다음의 예를 보면 ..
부서별 인원수를 구하는 SQL이다.
SQL> select deptno,count(*) from emp group by deptno;

DEPTNO COUNT(*)
---------- ----------
30 6
20 5
10 3

이 중인 인원수가 4이상인 부서를 출력한다. 즉 group 함수에 의해 계산된 값에 대한 조건이다.
SQL> select deptno,count(*) from emp group by deptno having count(*) > 4;

DEPTNO COUNT(*)
---------- ----------
30 6
20 5

아래의 SQL은 group by 에 의해 만들어진 결과에서 deptno가 20 이상인 부서만 출력한다.
SQL> select deptno,count(*) from emp group by deptno having deptno > 20;

DEPTNO COUNT(*)
---------- ----------
30 6

그러면 group by 절에 의한 결과에 대한 having과 select 절의 where 절은 바꿔 쓸 수 있을까?
아래의 결과를 보면 having deptno > 20 과 where deptno > 20의 결과는 같다. (당연한가?)

SQL> select deptno,count(*) from emp where deptno > 20 group by deptno;

DEPTNO COUNT(*)
---------- ----------
30 6

그러나 having 절에 의한 조건은 filter 처리로 계산된 결과에서 특정 조건만을 걸러내고 있으나,
where 절의 경우 access 처리로 scan의 범위를 줄이고 있음을 알 수 있다.

SQL> select deptno,count(*) from emp group by deptno having deptno > 20;

------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 6 | 3 (34)| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | HASH GROUP BY | | 2 | 6 | 3 (34)| 00:00:01 |
| 3 | INDEX FAST FULL SCAN| EMP_IDX04 | 449 | 1347 | 2 (0)| 00:00:01 |
------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("DEPTNO">20)

SQL> select deptno,count(*) from emp where deptno > 20 group by deptno;

----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 6 | 1 (0)| 00:00:01 |
| 1 | SORT GROUP BY NOSORT| | 2 | 6 | 1 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | EMP_IDX03 | 193 | 579 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("DEPTNO">20)

queyr의 결과는 동일하나 access 하는 범위 자체가 틀리니 이에 대한 주의가 필요하다.
당연히 access 범위를 줄일 수 있는 조건은 where 절에 기술하는 것이 유리할 듯 !!

근데, 테스트 하다보니 아래처럼 수행해도 결과가 잘 나오더군요.
select는 count를 했으나 having에는 sum으로 조건을 주어도 결과가 잘 나오네요.

SQL> select deptno,count(*) from emp group by deptno having sum(sal) > 10000;

DEPTNO COUNT(*)
---------- ----------
20 5

Execution Plan
----------------------------------------------------------
Plan hash value: 3110987654

----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 28 | 13 (8)| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | HASH GROUP BY | | 4 | 28 | 13 (8)| 00:00:01 |
| 3 | TABLE ACCESS FULL| EMP | 449 | 3143 | 12 (0)| 00:00:01 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(SUM("SAL")>10000)

그럼 group by에 의한 수행 결과에 대해 조건을 주는 것이 아니라
group by에 의해 나올 수 있는 결과에 대해 조건을 줄 수 있다는 거군요..

count(*)와 sum(sal)은 operation 자체가 다른데, 이걸 다 계산하고 있다는 건가?
아니면 having에 있는 sum()이 query 수행시 참조되는 건가?

"The HAVING clause is closely associated with the GROUP BY clause. The HAVING clause is used to put a filter on the groups created by the GROUP BY clause. If a query has a HAVING clause along with a GROUP BY clause, the result set will include only the groups that satisfy the condition specified in the HAVING clause."

네, having 절에 있는 group operation도 참조되는 게 맞습니다.. ^^

SQL> select deptno from emp group by deptno having sum(sal) > 10000;

DEPTNO
----------
20

'먹고살기 > Oracle' 카테고리의 다른 글

오라클함수 TO_CHAR (datetime)  (0) 2011.04.22
[Oracle] distinct, rowid 중복제거, 최신 데이터 하나만 가져오기  (0) 2011.04.15
select구문  (0) 2011.04.06
오라클 유저 생성  (0) 2011.04.05
시간 날짜 계산  (0) 2011.04.05
select구문 먹고살기/Oracle 2011. 4. 6. 15:21
9. 2000년 이후 입사자 출력
SELECT *
FROM employees
WHERE hire_date >= '00/01/01';


10. 문자열의 정렬(문자도 크기를 갖는다)
SELECT *
FROM jobs
WHERE job_title > 'President';

11. 논리연산자 OR를 이용한 조건식
SELECT *
FROM jobs
WHERE job_title = 'President'
OR job_title = 'Sales Manager';

12. 논리연산자 AND를 이용한 조건식
SELECT *
FROM employees
WHERE salary >= 10000
AND TO_CHAR(hire_date, 'YYYY') = '1994';

문제) 급여가 5000~10000인 사원 출력

문제) manager_id가 147이고, department_id가 80인 사원 출력


13. between~and : 논리연산자 AND의 특수한 상황
--급여가 5000~10000인 사원 출력
SELECT * FROM employees
WHERE salary BETWEEN 5000 AND 10000;

14. IN : 논리연산자 OR의 특수한 상황 -> 자주 사용하는 표현
SELECT *
FROM jobs
WHERE job_title IN ('President', 'Sales Manager');

14. LIKE : 부분 문자열을 이용한 조건. 패턴문자와 함께 사용.
--이름이 특정 글자로 시작하는 경우
SELECT *
FROM employees
WHERE first_name LIKE 'St%';

문제) 전화번호 지역번호가 650인 경우만 출력.
전화번호는 650.123.1234 형태로 구성됨. LIKE 연산자 이용.


문제) employees 테이블에서 first_name의 두번째 글자가 'an'인 경우만 출력
SELECT *
FROM employees
WHERE first_name LIKE '_an%';


15. IS NULL : NULL 값 확인
SELECT *
FROM employees
WHERE commission_pct IS NULL;

SELECT *
FROM employees
WHERE commission_pct IS NOT NULL;


-------------------------------------
ORDER BY 구문 사용
- 순서 지정
- ASC(Ascending, 오름차순), DESC(Desceding, 내림차순)


16. 이름순으로 정렬해서 출력
SELECT *
FROM employees
ORDER BY first_name ASC;

17. 급여를 기준으로 내림차순 정렬해서 출력
SELECT *
FROM employees
ORDER BY salary DESC;

문제) 커미션을 받는 사원 정보 출력하되, 급여가 높은순으로 출력.
SELECT
FROM
WHERE
ORDER BY


-------------------------------------
집계 함수
- SUM(), AVG(), COUNT(), MAX(), MIN()
- 주의. 집계 함수는 집계 함수들만 단독으로 사용해야 합니다.

18. 직원의 수
SELECT COUNT(*) FROM employees;

19. 최대 급여의 액수
SELECT MAX(salary) FROM employees;

문제) 직원들의 평균 급여액
SELECT AVG(salary) FROM employees;


----------------------------------
GROUP BY 구문 사용
- 집계 함수와 같이 사용하기 위한 그룹 기준 제시
- SELECT 컬럼명, 집계함수 FROM 소스 GROUP BY 컬럼명;

20. job_id별 직원의 수 출력
SELECT job_id, COUNT(*) FROM employees GROUP BY job_id;


문제) 전화번호 앞 3자리를 가지고 지역별 직원의 수 출력.
SELECT SUBSTR(phone_number, 1, 3), COUNT(*)
FROM employees
GROUP BY SUBSTR(phone_number, 1, 3);

21. 입사년도별 직원의 수 출력. 년도별 정렬해서 출력.
SELECT TO_CHAR(hire_date, 'YYYY'),COUNT(*)
FROM employees
GROUP BY TO_CHAR(hire_date, 'YYYY')
ORDER BY TO_CHAR(hire_date, 'YYYY') ASC;


문제) 직무(job_id)별 직원의 평균 급여 출력.

문제) job_id별 직원의 수 출력. 입사년도가 1996년도만.

--------------------------------------------
HAVING 구문 사용
- GROUP BY 구문에서 조건 지정시 사용.
- WHERE 구문과 유사한 역할.

22. job_id별 직원의 수 출력. 단, 10명 이상인 경우만.
SELECT job_id, COUNT(*)
FROM employees
GROUP BY job_id
HAVING COUNT(*) >= 10;


문제) 직무(job_id)별 직원의 평균 급여 출력. 단, 10000달러 이상만 출력.
SELECT job_id, AVG(salary)
FROM employees
GROUP BY job_id
HAVING AVG(salary) >= 10000;

문제) 직무(job_id)별 직원의 평균 급여 출력.
단, 10000달러 이상이면서 직무가 'MAN'으로 끝나는 경우만 출력.