'2008/04'에 해당되는 글 32건
- 2008/04/29 교환정렬 버블정렬 선택정렬 삽입정렬
- 2008/04/29 쌍방합병(two-way merging) 정렬
- 2008/04/28 삽입정렬(Insertion Sort)
- 2008/04/26 소희 새로운 네티즌 뮤직..
- 2008/04/14 IN절
- 2008/04/14 ANY술어 검색
- 2008/04/14 키(Key)의 개념 및 종류 후보키, 기본기, 대체키, 외래키
- 2008/04/14 개체 무결성, 참조 무결성
- 2008/04/14 정규화 과정
- 2008/04/14 DDL(데이터 정의어), DML(데이터 조작어) , DCL(데이터 제어어)
- 2008/04/06 count() 속도 비교
- 2008/04/06 중복된 row 두개중 한개를 없애려면 어떻게 해야되죠?
- 2008/04/06 한 개의 statement로 특정 key값을 가진 row가 없을 때에만 insert
- 2008/04/06 sql random 1개 row 출력 예시
- 2008/04/06 봄은 영원히 계속되지 않는다
- 2008/04/06 "그게 시작이다"
- 2008/04/06 "그게 시작이다"
- 2008/04/06 최고의 건강 비결
- 2008/04/06 '인내'의 원칙
- 2008/04/06 매일 출가(出家)하는 정신으로 2008년 새해를
- 2008/04/06 [MySQL] alter table 명령어 ( foreign key )
- 2008/04/06 [MySQL] alter table 명령어
- 2008/04/06 Key and Index in ORACLE
- 2008/04/05 리눅스 알아두면 편한 파일들
- 2008/04/05 가압류
- 2008/04/05 넥타이매는법
- 2008/04/05 MySQL DataBase 서버 튜닝 - Connection과 Memory
- 2008/04/04 Microsoft Office PowerPoint Viewer 2007 한글판
- 2008/04/03 08년1회 정보처리 기능사필기_기출문제
- 2008/04/03 05 08년1회 정보처리 기사모의고사
#include <stdio.h>
void Exchange_Sort(int []); // 교환정렬
void Bubble_Sort(int []); // 버블정렬
void Select_Sort(int []); // 선택정렬
void Insert_Sort(int []); // 삽입정렬
void Print(int []); // 정렬 된 배열출력
#define MAX 10
void main()
{
int i, main_su[MAX], sub_su[MAX];
printf("** 정렬할 수 %d개를 입력하십시오 **\n",MAX);
printf("** 입력 배열 => ");
for(i=0; i<MAX; i++){
scanf("%d",&main_su[i]);
sub_su[i] = main_su[i];
}
printf("\n\n** 교환 정렬 = > ");
Exchange_Sort(sub_su);
for(i=0; i<MAX; i++){ // 배열 상태 초기화
sub_su[i] = main_su[i];
}
printf("** 버블 정렬 = > ");
Bubble_Sort(sub_su);
for(i=0; i<MAX; i++){ // 배열 상태 초기화
sub_su[i] = main_su[i];
}
printf("** 선택 정렬 = > ");
Select_Sort(sub_su);
for(i=0; i<MAX; i++){ // 배열 상태 초기화
sub_su[i] = main_su[i];
}
printf("** 삽입 정렬 = > ");
Insert_Sort(sub_su);
}
void Exchange_Sort(int a[])
{
int i, j, temp;
for(i=0; i<MAX; i++){
for(j=i+1; j<MAX; j++){
if(a[i]>a[j]){
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
Print(a);
}
void Bubble_Sort(int a[])
{
int i, j, temp;
for(i=0; i<MAX; i++){
for(j=0; j<MAX-1; j++){
if(a[j]>a[j+1]){
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
Print(a);
}
void Select_Sort(int a[])
{
int i, j, temp, min;
for(i=0; i<MAX-1; i++){
min = i;
for(j=i+1; j<MAX; j++){
if(a[min]>a[j])
min = j;
}
temp = a[i];
a[i] = a[min];
a[min] = temp;
}
Print(a);
}
void Insert_Sort(int a[])
{
int i, j, temp;
for(i=1; i<MAX; i++){
temp = a[i];
j=i-1;
while(j>=0 && a[j]>temp){
a[j+1] = a[j];
j--;
}
a[j+1] = temp;
}
Print(a);
}
void Print(int a[])
{
int i;
for(i=0; i<MAX; i++)
printf("%d ",a[i]);
printf("\n");
}
3년 전에 작성한 source - 랩실 애들 세미나 출제용.
1. 분할 : 배열을 n/2개 아이템을 가진 2개의 부분배열로 분할한다.
2. 정복 : 정렬함으로써 각 부분배열을 정복한다. 배열이 충분히 작지 않으면 재귀 호출을 한다.
3. 통합 : 부분배열에 대한 답들을 합병하여 하나의 정렬된 배열로 만든다.
입력 : 양의 정수 n, 키의 배열 Array(첨자 1부터 n까지)
출력 : 키가 오름차순으로 정렬된 배열 Array
{
if ( n > 1 ) {
const keyword h = ↓[n / 2];
Keyword m = n - h;
keyword Left[h-1], Right[m-1];
for ( keyword i = 1; i <= h; i++)
Left[i] = Array[i];
for ( keyword i = 1; i <= m; i++)
Right[i] = Array[h+i];
merge_Sort(h, Left);
merge_Sort(m, Right);
merge(h, m, Left, Right, Array);
}
}
입력 : 양의 정수 h 와 m, 정렬된 키의 배열 Left(첨자 1부터 h까지),
정렬된 키의 배열 Right(첨자 1부터 m까지), 정렬된 키의 배열
출력 : Left와 Right의 키들을 모두 포함하여 정렬한 배열 Array(첨자 1부터 h+m까지)
const keyword right[], keyword Array[] )
{
keyword i, j, k;
i = 1; j = 1; k = 1;
while ( i <= h && j <= m) {
if ( Left[i] < Right[i] ) Array[k] = Left[i++];
else Array[k] = Right[j++];
k++;
}
if ( i > h) {
for ( keyword a = k; a <= h+m; a++)
Array[a] = Right[j];
}
else {
for ( keyword a = k; a <= h+m; a++)
Array[a] = Left[i];
}
}
표 2.1을 보면 크기가 4인 두 개의 배열을 합병할 때 mergy 알고리즘이 어떻게 작동하는 지 보여준다.
* 입력크기 : 두 입력 배열 아이템의 수, h와 m
* 입력크기 : 배열 Array의 아이템의 수, n
배열 Left 배열 Right 합병하는 데
정렬 시간 정렬 시간 걸린 시간
= 2W(n/2)+n-1
이 재현식은 다음과 같이 풀 수 있다.
참고 : Foundations of Algorithm, using C++ Pseudocode - 3rd Edition
[출처] 분할정복법 (합병정렬)|작성자 조똥꼬
처음 i-1배열슬롯(slot)의 키들이 정렬되어 있다고 가정한다. x를 i번째 슬롯에 있는 키 값이라 하자. x와 (i-1)번째 슬롯에 있는 키, (i-2)번째 슬롯에 있는 키, …, 등등 차례로 비교하되, x보다 작은 키를 찾을 때까지 이를 계쏙한다. j를 그 키가 위치한 슬롯이라고 하자. (j+1)번째 슬롯에서 (i-1)번째 슬롯에 있는 키들을 (j+2)번째 슬롯에서 i번째 슬롯으로 옮기고(move), (j+1)번째 슬롯에 x를 삽입한다. 이 과정을 i=2에서부터 i=n까지 반복한다. 다음 그림에서 이 정렬을 잘 설명해 준다.
삽입정렬의 알고리즘은 다음과 같다.
알고리즘) 삽입정렬 ------------------------------------------------------------
* 문제 : 비내림차순으로 n개 키를 정렬.
* 입력 : 양의 정수 n; 키의 배열 S(인덱스는 1부터 n)
* 출력 : 비내림차순으로 정렬된 키들로 구성된 배열 S
void insertionsort ( int n, keytype S[])
{
index i, j;
keytype x;
for( i = 2; i <= n; i++)
{
x = S[i];
j = i - 1;
whlie(j > 0 && S[j] > x)
{
S[j + 1] = S[j];
j--;
}
S[j + 1] = x;
}
}
---------------------------------------------------------------------------
참고 : Foundations of Algorithm, using C++ Pseudocode - 3rd Edition
필드의 값이 in 연사자의 인수로 지정된 값과 같은 레코드만 검색한다.
문법: where 필드 똔느 필드를 나타내는 식
IN 술어를 사용하여 하위 쿼리의 일부 레코드와 같은 값을 가진 기본 쿼리의 레코드만을 검색할 수 있습니다. 다음 예제는 70% 이하 할인된 제품을 모두 반환한다.
SELECT * FROM Products
WHERE ProductID IN
(SELECT ProductID FROM OrderDetails
WHERE Discount <= .70);
In
IN OPERATOR 를 사용하여 나열된 값들 중에서 값을 검사한다.
IN(LIST), NOT IN(LIST)
[ 예제 ]
S_EMP TABLE에서 DEPT_ID 가 20 , 21, 61 혹은 70 인 사원의 FIRST_NAME,
LAST_NAME, DEPT_ID 를 검색하시오.
SELECT FIRST_NAME, LAST_NAME, DEPT_ID
FROM S_EMP
WHERE DEPT_ID IN (20, 21, 61, 70) ;
ANY술어를 사용하여 하위 쿼리에서 검색된 레코드와 일치하는 기본 쿼리의 레코드를 검색할 수 있다. 다음 예제는 25% 이상 할인하여 판매한 어떤 제품의 가격보다 단가가 비싼 제품을 모두 반환한다.
SELECT * FROM Products
WHERE UnitPrice > ANY
(SELECT UnitPrice FROM OrderDetails
WHERE Discount >= .25);
데이터베이스에서 조건에 만족하는 튜플을 찾거나 순서대로 정렬할 때 기준이 되는 애트리뷰트
|
후보키 (Candidate Key) |
․릴레이션을 구성하는 속성들 중에서 튜플을 유일하게 식별하기 위해 사용하는 속성들의 부분집합, 즉 기본키로 사용할 수 있는 속성들을 말함 ․릴레이션에 있는 모든 튜플에 대해서 유일성과 최소성을 만족시켜야 함 |
|
기본키 (Primary Key) |
․후보키 중에서 선택한 주키(Main Key) ․한 릴레이션에서 특정 튜플을 유일하게 구별할 수 있는 속성 ․Null 값을 가질 수 없음 ․기본키로 정의된 속성에는 동일한 값이 중복되어 저장될 수 없음 |
|
대체키 (Alternate Key) |
․후보키가 둘 이상일 때 기본키를 제외한 나머지 후보키들을 말함 ․보조키라고도 함 |
|
슈퍼키 (Super Key) |
․릴에이션에서 같은 튜플이 발생하지 않는 키를 구성할 때, 속성의 집합으로 구성하는 것을 말함 ․릴레이션을 구성하는 모든 튜플에 대해 유일성은 만족시키지만, 최소성은 만족시키지 못함 |
|
외래키 (Foreign Key) |
․관계(Realtionship)를 맺고 있는 릴레이션 R1, R2에서 릴레이션 R1이 참조하고 있는 릴레이션 R2의 기본키와 같은 R1 릴레이션의 속성 ․외래키로 지정되면 참조테이블의 기본키에 없는 값은 입력할 수 없음 |
※ 널 값(NULL Value) : 데이터베이스에서 아직 알려지지 않거나 모르는 값으로서 "해당없음" 등의 이유로 정보 부재를 나타내기 위해 사용하는, 이론적으로 아무것도 없는 특수한 데이터
[출처] 키(Key)의 개념 및 종류 후보키, 기본기, 대체키, 외래키|작성자 쇼부정신
▪개체 무결성 : 릴레이션에서 기본키를 구성하는 속성은 널(NULL) 값이나 중복값을 가질 수 없음
예) ‘학생’ 릴레이션에서 ‘학번’이 기본키로 정의 되면 튜플을 추가할 때 ‘주민번호’나 ‘성명’ 필드에는 값을 입력하지 않아도 되지만 ‘학번’ 속성에는 반드시 값이 입력되어야 함, 또한 ‘학번’ 속성에는 이미 한 번 입력한 속성 값을 중복하여 입력할 수 없음
▪참조 무결성 : 외래키 값은 NULL이거나 참조 릴레이션의 기본키 값과 동일해야 함 즉, 릴레이션은 참조할 수 없는 외래키값을 가질 수 없음
예) ‘수강’ 릴레이션의 ‘학번’ 속성에는 ‘학생’ 릴레이션의 ‘학번’ 속성에 없는 값은 입력할 수 없음
[출처] 개체 무결성, 참조 무결성|작성자 쇼부정신
|
비정규 릴레이션 |
|
↓ 도메인이 원자 값 |
|
INF |
|
↓ 부분적 함수 종속 제거 |
|
2NF |
|
↓ 이행적 함수 종속 제거 |
|
3NF |
|
↓ 결정자이면서 후보키가 아닌 것 제거 |
|
BCNF |
|
↓ 다치종속 제거 |
|
4NF |
|
↓ 조인 속성 이용 |
|
5NF |
정규화 단계 암기 요령
정규화라는 출소자가 말했다.
두부이겨다줘≒도부이결다조
도 메인이 원자값
부 분적 함수 종속 제거
이 행적 함수 종속 제거
결 정자이면서 후보키가 아닌 것 제거
다 치 종속 제거
조 인 종속성 이용
DDL(데이터 정의어)
▪SCHEMA, DOMAIN, TABLE, VIEW, INDEX를 정의하거나 변경 또는 삭제할 때 사용하는 언어
▪데이터베이스 관리자나 데이터베이스 설계자가 사용함
▪데이터 정의어(DDL)의 3가지 유형
|
명령어 |
기 능 |
|
CREATE |
Schema, Domain, Table, View, Index를 정의함 |
|
ALTER |
Table에 대한 정의를 변경하는 데 사용함 |
|
DROP |
Schema, Domain,Table, View, Index를 삭제함 |
DML(데이터 조작어)
▪데이터베이스 사용자가 응용 프로그램이나 질의어를 통하여 저장된 데이터를 실질적으로 처리하는데 사용하는 언어
▪데이터베이스 사용자와 데이터베이스 관리 시스템 간의 인터페이스 제공
▪데이터 조작어(DML)의 4가지 유형
|
명령어 |
기능 |
|
SELECT |
테이블에서 조건에 맞는 튜플을 검색함 |
|
INSERT |
테이블에 새로운 튜플을 삽입함 |
|
DELETE |
테이블에서 조건에 맞는 튜플을 삭제함 |
|
UPDATE |
테이블의 조건에 맞는 튜플의 내용을 변경함 |
DCL(데이터 제어어)
▪데이터의 보안, 무결성, 데이터 회복, 병행 수행 제어 등을 정의하는 데 사용하는 언어
▪데이터베이스 관리자가 데이터 관리를 목적으로 사용함
▪데이터 제어어(DCL)의 종류
|
명령어 |
기능 |
|
COMMIT |
데이터베이스 조작 작업이 정상적으로 완료되었음을 관리자에게 알려줌 |
|
ROLLBACK |
데이터베이스 조작 작업이 비정상적으로 종료되었을 때 원래의 상태로 복구함 |
|
GRANT |
데이터베이스 사용자에게 사용권한을 부여함 |
|
REVOKE |
데이터베이스 사용자의 사용권한을 취소함 |
count() 속도 비교
필드명들: num, num2, num3, num4
num 에서 1번 값만 카운트 시킨다고 했을때,
[쿼리]
1: select count(*) A where num=1;
2: select count(num) A where num=1;
3: select count(1) A where num=1;
1, 2, 3번 쿼리중에 어떤 게 제일 빠른가요?
count() 와 같은 집계함수는 그것이 호출될때 아마도 내부적으로는 누적을 하는 루틴을 가지고 있을 겁니다.
즉, 하나가 들어오면 그것에 누적하는 방식인데요..
그러므로 갯수를 하나하나 세게 됩니다.
count(num) 했을 경우는 num col 을 세개 될 테고요...
count(*) 는 모든 컬럼에 대해 즉, row 자체를 세개 되는 것이고요
count(1) 은 1 이 나오는 결과 즉 select 1 from table where ...; 와 같이
결과값이 1 이 나오는 것을 하나하나 세개 됩니다.
결국은 하나하나 세는 건 마찬가지다..라는것이 이론적인 개념입니다.
즉,, 무엇을 하던지 똑같은 결과가 나와야 하지 않느냐..라는 것인데요
DB 마다 count 로직이 다를수도 있고, dictionary 나 자체 정보 데이타를 가지고 잇는 것들도 있으니,
내부적으로 어떻게 counting 하느냐에 따라 달라질수 있겠죠..
암튼.. 이론상으로는 같은 결과라 생각되네요
단 요 위에도 있듯이.. col 을 직접 명시하여 count 할때는
상황에 따라 다른 결과가 나올수 있다는 정도..가 다르겠네요
한 개의 statement로 특정 key값을 가진 row가 없을 때에만 insert

이 럴 경우, lock을 걸어주지 않으면 select와 insert 사이에 또 다른 insert request가 발생할 겨우에 consistency가 깨어져 2번 insert가 되는 경우가 발생한다. 이를 해결하기 위해 lock(transaction)을 사용할 경우에는 심각한 성능저하가 발생할 수 있다.
하지만 이런 경우 아주 간단히 ANSI SQL을 통해 해결할 수 있는 방법이 있다.
ansi sql중 insert bnf
위의 link를 따라가보면, insert의 bnf를 볼 수 있는데, 여기서 활용할 구문은 <from_subquery>이다.
insert into a_table
select 'key1', 'key2', 'key3', 'etc_col1', 'etc_col2'
from
a_table_with_only_one_column
where (key1, key2, key3) not in
(select key1, key2, key3
from a_table where key1='key1' and key2='key2' and key3='key3')
단지 row가 딱 하나만 들어있는 공용 table이 필요하다는 것만 주의하면 된다.
a_table_with_only_one_column 은 oracle에서 dual, 혹은 DB2에서의 SYSIBM.SYSDUMMY1과 같은 역할을 하게 되며, 호환성을 위해 하나의 application 영역에 하나의 테이블을 별도로 만들어 공유해서 사용하면 된다.
insert가 되었는지 안되었는지는 결과값만 확인하면 된다. insert된 row 수가 1이면 insert가 된거고 0이면 기존에 key를 가진 row가 있었다는 의미이다.
MySQL:
SELECT column FROM table ORDER BY RAND() LIMIT 1
PostgreSQL:
SELECT column FROM table ORDER BY RANDOM() LIMIT 1
Microsoft SQL Server:
SELECT TOP 1 column FROM table ORDER BY NEWID()
IBM DB2:
SELECT column FROM table ORDER BY RAND() FETCH FIRST 1 ROWS ONLY
Oracle:
SELECT column FROM ( SELECT column FROM table ORDER BY dbms_random.value ) WHERE rownum = 1
만약 당신이 작가라면
주어진 시간이 얼마 남지 않았다는 각오로
글을 써야 한다. 이제 남아 있는 시간은 얼마 되지 않는다.
당신 영혼에 맡겨진 순간순간을 잘 활용하라. 영감(靈感)의 잔을
마지막 한 방울까지 마셔 비우도록 하라. 영감의 잔을 비우는
일에서 너무 지나치지 않을까 하고 두려워할 필요는 없다.
그렇게 하지 않으면 세월이 흐른 뒤 후회하게 될 것이다.
봄은 영원히 계속되지 않는다.
- 헨리 데이비드 소로의《소로의 속삭임》중에서 -
* '주어진 시간'이 짧은 것은
작가에게만 해당되는 말은 아닙니다.
봄이 그렇듯 우리의 삶 또한 영원히 계속되지 않습니다.
사랑할 시간, 감사할 시간은 더욱 빨리 지나갑니다.
영감의 잔, 사랑의 잔에 담긴 마지막 한 방울까지
남김없이 마셔 비워야 후회가 없습니다.