글쓴이 글 목록: opener

[mysql] 난수 생성기 – 쿠폰번호 발행 2015-07-07

쿠폰 발행시스템이나 api키 발행 등에 유연하고 쉽게 사용할 수 있도록 mysql stored function으로 구성해 보았다. 중복체크가 필요할 경우 별도의 프로시저를 만들어 필터링 하면 된다. 시간이 된다면 확장해서 쿠폰 시스템을 만들어 보아야 겠다.

Example

select create_random_key(INT length, BOOLEAN include_upper_case, BOOLEAN include_lower_case, BOOLEAN include_number, TINYINT(2) first_block_type);

Parameter

- length : 난수의 길이
- include_upper_case : 대문자 포함여부
- include_lower_case : 소문자 포함여부
- include_number : 숫자 포함여부
- first_block_type : 첫번째 문자 불가유형(0:미적용, 1:'0'안됨, 2:숫자안됨)
CREATE DEFINER=`root`@`%` FUNCTION `create_random_key`(`p_length` INT, `p_include_upper_case` BOOLEAN, `p_include_lower_case` BOOLEAN, `p_include_number` BOOLEAN, `p_first_block_type` TINYINT(2))
	RETURNS varchar(255) CHARSET utf8
	LANGUAGE SQL
	NOT DETERMINISTIC
	CONTAINS SQL
	SQL SECURITY DEFINER
	COMMENT '렌덤키를 생성'
BEGIN
/** 2014.05.25 - opal95 : create random key
 * IN
 * - p_length : key total length
 * - p_include_upper_case : 대문자 포함여부
 * - p_include_lower_case : 소문자 포함여부
 * - p_include_number : 숫자 포함여부
 * - p_first_block_type : 첫번째 문자 불가유형(0:미적용, 1:'0'안됨, 2:숫자안됨)
 * RETURN : 조합된 키값
**/

/* Define */
DECLARE v_return_key					VARCHAR(255) DEFAULT '';
DECLARE v_char_store					CHAR(1) DEFAULT '';
DECLARE v_done								INT DEFAULT 0;

/* Create Temporary Table */
DROP TEMPORARY TABLE IF EXISTS temp_random_key;
CREATE TEMPORARY TABLE temp_random_key(
	random_char CHAR(1),
	type TINYINT(2)
);
IF p_include_upper_case = true THEN 
	INSERT INTO temp_random_key (random_char, type) VALUES 
		/* upper case - 26 */
		('A', 1),('B', 1),('C', 1),('D', 1),('E', 1),('F', 1),('G', 1),('H', 1),('I', 1),('J', 1),
		('K', 1),('L', 1),('M', 1),('N', 1),('O', 1),('P', 1),('Q', 1),('R', 1),('S', 1),('T', 1),('U', 1),('V', 1),('W', 1),('X', 1),('Y', 1),('Z', 1);
END IF;
IF p_include_lower_case = true THEN
	INSERT INTO temp_random_key (random_char, type) VALUES 
		/* lower case - 26 */
		('a', 2),('b', 2),('c', 2),('d', 2),('e', 2),('f', 2),('g', 2),('h', 2),('i', 2),('j', 2),
		('k', 2),('l', 2),('m', 2),('n', 2),('o', 2),('p', 2),('q', 2),('r', 2),('s', 2),('t', 2),('u', 2),('v', 2),('w', 2),('x', 2),('y', 2),('z', 2);
END IF;
IF p_include_number = true THEN
	INSERT INTO temp_random_key (random_char, type) VALUES 
		/* number - 10 */
		('0', 3),('1', 3),('2', 3),('3', 3),('4', 3),('5', 3),('6', 3),('7', 3),('8', 3),('9', 3);
END IF;

/* Select Random_character */
/* - The first character is not zero */
IF p_first_block_type = 1 THEN
	SELECT random_char INTO v_return_key FROM temp_random_key WHERE random_char <> '0' ORDER BY rand() LIMIT 1;
	SET p_length = p_length - 1;
/* - The first character is not number */
ELSEIF p_first_block_type = 2 THEN
	SELECT random_char INTO v_return_key FROM temp_random_key WHERE type in (1, 2) ORDER BY rand() LIMIT 1;
	SET p_length = p_length - 1;
END IF;
/* - The remaining character */
WHILE p_length DO
	SELECT random_char INTO v_char_store FROM temp_random_key ORDER BY rand() LIMIT 1;
	SET v_return_key = CONCAT(v_return_key, v_char_store);
	SET p_length = p_length - 1;
END WHILE;

/* Return Key */
RETURN v_return_key;
END

coupon발행


coupon발행2


coupon발행3


coupon발행4

[문제해결] redis 시작시 에러 2015-07-07

1. 문제상황

> Linux-CentOS환경에서 Redis 서버가 시작되지 않았다.


2. 문제확인

> 로그파일(/var/log/redis/redis.log)을 확인하여 보니 다음과 같았다. 개발환경을 구축하기 위해 낮은사양의 서버에 여러 포트를 올려서 사용하였더니 기본 시스템 자원의 제한 값을 초과 한것이다.

[1016] 06 Jul 22:56:45.118 # You requested maxclients of 10032 requiring at least 10064 max file descriptors.
[1016] 06 Jul 22:56:45.123 # Redis can't set maximum open files to 10064 because of OS error: Operation not permitted.
[1016] 06 Jul 22:56:45.123 # Current maximum open files is 1024. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclie                                                  nts increase 'ulimit -n'.
* Current maximum open files is 1024. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclie                                                  nts increase 'ulimit -n'.
==> 현재 최대 열수있는 파일수는 1024이고 높게 조정하려면 ulimit -n 명령을 사용하라고 친절히 설명해 주고 있다.

3. 문제해결

> ‘ulimit’ 명령으로 시스템 자원의 제한 값을 확인하고 변경할 수 있다.

제한 값 확인
[root@redis]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 14806
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 14806
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
제한 값 변경
ulimit -n 32768
실행 로그 확인
cd                 _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 2.8.13 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in stand alone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6201
 |    `-._   `._    /     _.-'    |     PID: 29333
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

[29333] 07 Jul 13:18:18.240 # Server started, Redis version 2.8.13
[29333] 07 Jul 13:18:18.258 * DB loaded from disk: 0.017 seconds
[29333] 07 Jul 13:18:18.258 * The server is now ready to accept connections on p
* '-c' : core file의 최대크기
* '-d' : 프로세스 data segment의 최대크기
* '-p' : pipe 버퍼의 크기
* '-s' : stack의 최대크기
* '-n' : open 가능한 파일의 개수
* '-f' : 쉘에서 생성하는 파일의 최대크기
* '-t' : 할당받을 수 있는 cpu time
* '-v' : 프로세스가 할당 받을 수 있는 가상메모리의 크기
* '-t' : 할당받을 수 있는 cpu time
* '-a' : 모든 제한값 출력

[C++정리] 제네릭 프로그래밍을 위한 템플릿 사용 2015-07-06

제네릭 프로그래밍(Generic programming)이란 데이터 형식에 의존하지 않고, 하나의 값이 여러 다른 데이터 타입들을 가질 수 있는 기술에 중점을 두어 재사용성을 높일 수 있는 프로그래밍 방식으로 템플릿은 STL 제네릭 프로그래밍의 핵심이라고 할 수 있다.

#include "stdafx.h"
#include <iostream>

using namespace std;

// 오버로딩을 통한 구현
// - 함수 오버로드
void PrintOverload(int a, const char* b)
{
	cout << a << "::" << b << "\n";
}
void PrintOverload(double a, const char* b)
{
	cout << a << "::" << b << "\n";
}
// - 클래스 생성
class PrintClass1
{
public:
	PrintClass1(int a)
	{
		cout << a << "\n";
	}
};
class PrintClass2
{
public:
	PrintClass2(double a)
	{
		cout << a << "\n";
	}
};
class PrintClass3
{
public:
	PrintClass3(const char* a)
	{
		cout << a << "\n";
	}
};

// 템플릿을 통한 구현
// - 함수 템플릿
template<typename T1, typename T2>
void PrintTemplate(T1 a, T2 b)
{
	cout << a << "::" << b << "\n";
}
// - 클래스 템플릿
template<typename T=int, int number=10>
class PrintClassTemplate
{
public:
	PrintClassTemplate(T a)
	{
		cout << number << "::" << a << "\n";
	}
};

int _tmain(int argc, _TCHAR* argv[])
{	
	PrintOverload(10, "Overload");
	PrintOverload(11.1, "Overload");

	cout << "====================\n";

	PrintTemplate<int, const char*>(10, "Template");
	PrintTemplate<double, const char*>(11.1, "Template");

	cout << "====================\n";

	PrintClass1 printClass1(10);
	PrintClass2 printClass2(11.1);
	PrintClass3 printClass3("Class");

	cout << "====================\n";

	PrintClassTemplate<int, 1> printClass4(10);
	PrintClassTemplate<double, 2> printClass5(11.1);
	PrintClassTemplate<const char*, 3> printClass6("Class");
	// 매개변수에 아무값도 지정하지 않을경우
	// 기본형 typename T=int, int number=10으로 인식된다.
	PrintClassTemplate<> printClass7(10);

	return 0;
}
* 템플릿을 사용해 비슷한 유형의 클래스를 용도별로 구현하지 않고도 유연하게 활용할 수 있다.