웹 기반 모니터링 프로젝트에 대한 실시간 데이터 및 내역 데이터가 표시되었습니다. 샘플 주파수가 50Hz 인 거의 16 개의 센서가 있습니다. 센서의 모든 원시 데이터는 데이터베이스에 저장되어야하며, 초당 거의 900 개의 데이터에 도달합니다. 그리고 데이터는 최소 3 년 동안 저장되어야합니다. 데이터베이스는 Oracle 11g입니다.실시간 데이터 테이블 - 내역 데이터 테이블에 대한 데이터 손실
내 직업은 데이터 수집 프로그램을 작성하고 데이터베이스에 데이터를 저장할 센서 하드웨어 회사의 엔지니어를위한 데이터베이스 구조를 설계하는 것입니다.
실시간 데이터 테이블 및 내역 데이터 테이블이 설계되었습니다. 실시간 데이터 테이블과 히스토리에서 실시간 데이터를 읽습니다. 데이터는 히스토리 데이터 테이블에서 읽습니다.
실제 데이터 테이블은 1 분 데이터 만 저장 한 다음과 같습니다.
-
:
SQL 쿼리는 웹 클라이언트의 시간 기록을 기반으로합니다 (예 :
). 선택 ac_1에서 ac_test 여기서 record_time> = to_timestamp ('2016-08-01 00:00:00', 'yyyy-mm-dd hh24 : mi : ss') 그리고 record_time < = to_timestamp ('2016-08-01 00 : 30 : 00 ','yyyy-mm-dd hh24 : mi : ss ');
간격 파티션은 일에서 원거리입니다. 하루 동안 데이터를 테스트하는 동안 하루에 430 만 데이터에 대해 40 초가 소요되었습니다.
Create Table real_data(
record_time timestamp(3),
ac_1 Float,
ac_2 Float,
ac_3 Float,
ac_4 Float,
ac_5 Float,
ac_6 Float,
ac_7 Float,
ac_8 Float,
ac_9 Float,
ac_10 Float,
ac_11 Float,
ac_12 Float,
ac_13 Float,
ac_14 Float,
ac_15 Float,
ac_16 Float
)
Tablespace data_test;
는 히스토리 데이터 테이블의 구조는 간격 파티션 두 가지 이유 때문에 선택
Create Table history_data(
record_time timestamp(3),
ac_1 Float,
ac_2 Float,
ac_3 Float,
ac_4 Float,
ac_5 Float,
ac_6 Float,
ac_7 Float,
ac_8 Float,
ac_9 Float,
ac_10 Float,
ac_11 Float,
ac_12 Float,
ac_13 Float,
ac_14 Float,
ac_15 Float,
ac_16 Float
)
Tablespace data_test
PARTITION BY RANGE(record_time)
INTERVAL(numtodsinterval(1,'day'))
(
PARTITION P1 VALUES LESS THAN (TO_DATE('2016-08-01', 'YYYY-MM-DD'))
);
alter table history_data add constraint RECORD_DATE primary key (RECORD_TIME);
기본 키와 파티션 구성 실제 데이터와 동일
작업이 실행되어 1 분당 실제 데이터 - 이력 데이터 테이블이 전송됩니다. 전송 프로세스는 oracle 프로 시저에 의해 수행되고, 전송 시간은 다른 테이블 real_data_top_backup_date에 의해 기록됩니다.
create or replace procedure copy_to_history_test is
d_top_backup_date timestamp(3);
begin
select top_backup_date into d_top_backup_date from real_data_top_backup_date;
Insert Into history_data Select * From real_data where record_time <d_top_backup_date;
delete from real_data where record_time <d_top_backup_date;
Update real_data_top_backup_date Set top_backup_date=(d_top_backup_date+1/24/60);
commit;
end copy_to_history_test;
시뮬레이션 데이터를 수집하고 삽입하는 시뮬레이션 프로그램이 작성되었습니다.
Declare
time_index Number;
start_time Timestamp(3);
tmp_time Timestamp(3);
tmp_value1 Float;
tmp_value2 Float;
tmp_value3 Float;
tmp_value4 Float;
tmp_value5 Float;
tmp_value6 Float;
tmp_value7 Float;
tmp_value8 Float;
tmp_value9 Float;
tmp_value10 Float;
tmp_value11 Float;
tmp_value12 Float;
tmp_value13 Float;
tmp_value14 Float;
tmp_value15 Float;
tmp_value16 Float;
Begin
--initiaze the variable
time_index:=0;
SELECT to_timestamp('2016-08-01 00:00:00:000', 'yyyy-mm-dd h24:mi:ss:ff') Into start_time FROM DUAL;
While time_index<(50*60*60*24*7)
Loop
-- add 20 millionseconds
SELECT start_time+numtodsinterval((0.02*time_index),'SECOND') Into tmp_time FROM DUAL;
-- dbms_output.put_line(tmp_time);
-- create random number
select dbms_random.value Into tmp_value1 from dual ;
select dbms_random.value Into tmp_value2 from dual ;
select dbms_random.value Into tmp_value3 from dual ;
select dbms_random.value Into tmp_value4 from dual ;
select dbms_random.value Into tmp_value5 from dual ;
select dbms_random.value Into tmp_value6 from dual ;
select dbms_random.value Into tmp_value7 from dual ;
select dbms_random.value Into tmp_value8 from dual ;
select dbms_random.value Into tmp_value9 from dual ;
select dbms_random.value Into tmp_value10 from dual ;
select dbms_random.value Into tmp_value11 from dual ;
select dbms_random.value Into tmp_value12 from dual ;
select dbms_random.value Into tmp_value13 from dual ;
select dbms_random.value Into tmp_value14 from dual ;
select dbms_random.value Into tmp_value15 from dual ;
select dbms_random.value Into tmp_value16 from dual ;
--dbms_output.put_line(tmp_value);
-- Insert Into ac_data (sensor_id,data,record_time) Values(sensor_index,tmp_value,tmp_time);
Insert Into real_data Values(tmp_time,tmp_value1,tmp_value2,tmp_value3,tmp_value4,tmp_value5,tmp_value6,tmp_value7,tmp_value8,tmp_value9,tmp_value10,tmp_value11,tmp_value12,tmp_value13,tmp_value14,tmp_value15,tmp_value16);
if mod(time_index,50)=0 then
commit;
dbms_lock.sleep(1);
End If;
time_index:=time_index+1;
End Loop;
-- dbms_output.put_line(c);
Exception
WHEN OTHERS THEN
log_write('insert data failure!');
End;
문제는 전송 데이터 절차 중에 거의 0.1 % 양의 센서 데이터가 손실된다는 것입니다. 나는 데이터 전송 (데이터 삽입 및 데이터 삭제)의 병렬 작업이 데이터 손실로 이어진다 고 생각합니다. 문제를 해결하는 방법?
또한이 시나리오에서 데이터베이스 구조가 실현 가능합니까? 데이터베이스를위한 또 다른 더 좋은 디자인이 있습니까?
데이터가 손실되었음을 어떻게 알았습니까? –
@ EvgeniyK.나는 하루 동안 4316850 센서 데이터가 있다는 것을 알았고 howerver는 432000 데이터로 구성됩니다. – skyspeed