대규모 MS Access 응용 프로그램을 .Net으로 옮기는 모범 사례?


26

우리는 개인 요구에 맞게 자체 개발 한 거대한 MS Access 애플리케이션을 상용 소프트웨어로 전환하여 성공적으로 판매했습니다. 이 소프트웨어는 일종의 "비즈니스를위한 모든 소프트웨어"이며 문서 관리 시스템, 기업 자원 계획, 재고 관리, 고객 관계 관리, 데이터 분석 등 여러 모듈을 포함합니다. 고객의 요청을 충족시키기 위해 새로운 무언가로 옮겨 가야한다는 것을 깨달았습니다.

우리는 Visual Basic .Net을 고수 할 수 있기 때문에 응용 프로그램을 .Net으로 점진적으로 옮기기로 결정했습니다. 여기에서는 대부분의 개발자에게 새로운 언어이지만 VBA와 VB6에서 구현 된 수십 개의 소규모 프로젝트에 대해 깊이 알고 있습니다.

우리는 이미 모든 데이터 조작 및 검색이 서버에서 직접 수행되도록 응용 프로그램의 데이터 계층 기능을 MS SQL Server로 이전하기 시작했습니다.

우리가 찾고있는 것은 광범위한 GUI (하위 양식을 포함한 약 500-600 개의 다른 양식, 다국어 지원을 포함한 약 200 개의 보고서 등)를 점차적으로 이동시키는 모범 사례입니다. DMS 문서에서 비동기 데이터 암호화를 구현하려는 잠재 고객의 최근 요청에 따라이 부분을 MS Access에서 완전히 분리하여 .Net에서 구현하게되어 기쁩니다.

문제는 .Net 응용 프로그램을 기존 MS Access 시스템과 원활하게 통합하여 특정 매개 변수 (사용자 권한 등)로 호출하고이 응용 프로그램과 실행중인 MS Access 응용 프로그램간에 데이터를 교환 할 수 있도록하는 방법입니다.


편집하다:

우리는 Martin Fowler의 저서 " 엔터프라이즈 통합 패턴 (Enterprise intergration patterns) " 의 일부 관행을 적용 하여 MS Access 응용 프로그램과 다양한 요구를 위해 .Net에서 구현 한 작은 유틸리티 간의 통합을 달성했습니다. 그러나 우리는 "공유 데이터베이스"패턴 만 사용했고 실제로는 솔루션에 만족하지 않았습니다.

예를 들어, POP3 연결을 사용하여 메일 서버에서 모든 메시지를 자동으로 다운로드하여 하나의 테이블에 저장하는 Windows 서비스로 실행되는 작은 유틸리티를 구현했지만 모든 첨부 파일은 파일 시스템에 저장되었습니다.

우리가 주로 한 것은 ADO.NET을 사용하여 MDB 형식의 MS Access 데이터베이스에 직접 액세스하고 처리 된 데이터로 테이블을 채우는 것입니다 (위 예의 메일 메시지에 대한 데이터 등). FROM, TO, CC, BCC, 대상 및 신체).

.Net의 MDB 데이터 형식으로 작업하는 데 전혀 문제가 없으며 , MDB를 유지하고 싶지 않으며 거의 ​​모든 것을 MS SQL Server 2008로 업 사이징하지 않기 때문에 데이터 관리 및 확장 성과 관련하여 훨씬 더 많은 자유를 얻을 수 있습니다.

여기서 중요한 문제는 데이터 업데이트시 특정 VBA 코드의 실행을 트리거 할 수 있도록 Access에서 일종의 "콜백"을 구현하는 방법을 모른다는 것입니다 .

데이터 테이블에 대한 업데이트 및 삽입 트리거를 지원하는 MS Access 2010에 큰 희망이 있었지만 이러한 트리거에 대해서만 MS Access 매크로를 사용할 수 있으며 트리거 내에서 사용자 지정 VBA 코드를 실행할 수있는 방법이 없습니다.

또한 사용자가 호출 한 일부 데이터 쿼리를 흉내 내기 위해 키 입력을 MS Access 창 으로 직접 보내는 솔루션도 시도했습니다 . 이것은 작동하지만 프로덕션 환경에서 사용할 수있는 실현 가능한 솔루션이라고는 생각하지 않습니다.

또한 MS Access 용 DDE를 조사했지만 DDE 명령을 구현 하고 메모리 내 데이터 및 명령 교환에 사용하는 좋은 샘플 솔루션을 찾을 수 없었 습니다.

따라서 주요 문제는 MS Access와 .Net 응용 프로그램이 공존하고 상호 작용하는 것입니다.

EDIT2 :

.Net과 MS Access 사이의 메시지 전달을 위해 VBA에서 MSMQ 라이브러리를 구현 한 것을 언급하는 것을 잊어 버렸습니다 . 문제는 다시 콜백이 부족하다는 것입니다. 새 메시지에 대한 대기열을 실제로 폴링하고 VBA가 실제로 지원하지 않는다는 점을 감안할 때 멀티 스레딩 그것은 정말 좋은 해결책이 아니 었습니다.


작은 개념 증명 .NET 앱을 사용하여 두 부분이 얼마나 잘 협력하는지 확인할 수 있습니까? 어떤 문제가 발생 했습니까?
sq33G

Access 응용 프로그램은 어떻게 배포됩니까? 그리고 인증 기술은 무엇입니까?
Skrol29

@ sq33G :이 주제를 다루기 위해 질문을 편집했습니다.
Alexander Galkin

@ Skrol29 : 일반적으로 MS Access 런타임과 함께 컴파일 된 MDB (.MDE)로 배포합니다. 데이터베이스 연결 및 권한에 대해 Active Directory를 통해 관리되는 Windows 인증을 사용합니다.
Alexander Galkin

3
좋은 질문입니다. "모든 것을 다"Access 데이터베이스가 늘어나는 요구에 맞춰 확장 할 수없는 경우, 빠르게 성장하는 많은 비 소프트웨어 회사가 종종 직면하고 개발자의 실수에 처하게되는 매우 실용적인 문제입니다.
bunglestink

답변:


17

이 프로젝트는 크고 규모가 큰 프로젝트가 될 것입니다. Access 데이터베이스를 .NET으로 여러 번 마이그레이션하는 작업을 담당했지만이 규모로는 결코 사용하지 않았습니다. 점진적인 접근 방식이 아마도 가장 현실적 일 것입니다. 한 번에 모든 것을 받아들이는 것은 실패하기 쉬운 방법입니다.

다른 답변과 마찬가지로 첫 번째로 가장 중요한 단계는 모든 것을 SQL Server로 옮기는 것입니다. 이 작업을 수행하는 동안 데이터베이스가 아직 완료되지 않은 경우 데이터베이스를 문서화하고 리팩토링 영역이 있는지 확인하십시오. 진화하는 요구를 충족시키기 위해 성장하는 액세스 데이터베이스에는 종종 큰 그림을 볼 때 개선 될 수있는 데이터 모델이 있습니다.

다음으로 "자체 포함 된"애플리케이션의 모듈을 식별하십시오. 이 데이터베이스는 모든 작업을 수행하기 때문에 서로 완전히 분리되어있는 모듈이있을 수 있습니다. 이러한 분리 된 조각을 가지고 나면 업데이트를 통해 얻을 수있는 가장 작은 모듈 중 하나를 식별하여 먼저 가져옵니다.

.NET으로 마이그레이션하는 동안 응용 프로그램의 단순한 일대일 사본 만 수행하지 마십시오. 현재 응용 프로그램으로 문제를 식별하기 위해 사용자로부터 입력을 수집하십시오. 첫 번째 마이그레이션 단위가 다른 사람으로부터 완전한 구매를 얻는 데 큰 성공을 거두기를 원합니다.

첫 번째 단원을 마친 후에는 도전, 어려움 등의 측면에서 어떤 일이 있었는지 살펴보고이를 활용하십시오.

내가 권장하지 않는 한 가지는 부분적으로 작동하는 모듈을 구현하는 것입니다 (예 : "CRM을 마이그레이션했지만 기능 X, Y, Z는 아직 새 시스템에 없습니다"). 이로 인해 오래된 시스템이 "완전히 훌륭"했을 때 불완전한 시스템을 사용하는 것이 사용자에게 빨리 좌절감을 줄 것입니다. 이러한 종류의 개발은 다른 도메인에서는 잘 작동 할 수 있지만 사용자가 기존 Access 단일체에서 "아무것도없는 것"을보고 마이그레이션 요구를 이해하지 못하는 비즈니스에는 적합하지 않습니다.


1
여러 언어를 지원할 수 있으면 훨씬 쉬워집니다. 여러 언어를 지원할 수있는 디자인 결정을 내려야하는 반면, 특정 요소에 대해 제안 된대로 번글 스틴 크에 집중해야합니다. 또한 모든 양식에 대한 레이아웃과 흐름을 제시하고 100 % 완전하지 않은 양식에 대한 링크를 피하면 부분 기능을 피할 수 있습니다.
Ramhound

7

다음은 돌연변이에 의해 MS Access 응용 프로그램을 VB.Net 응용 프로그램으로 전환하는 일종의 계획입니다.

이것은 일반적인 계획이 아니며, 다음 계획은 설명한 프로젝트에 따라 다릅니다.

1 단계 : 모든 데이터를 SQL Server로 마이그레이션

SQL Server 연결에 ODBC를 사용하지 말고 대신 ADP (Access Project)를 사용하십시오. Access 프로젝트는 확장명이 .adp 인 Access 파일이며 전체 액세스 기능 (매크로, 양식, 보고서, 모듈)이 있지만 연결은 MDB 파일 대신 SQL Server 데이터베이스에 직접 연결되어 있습니다. ADP 파일은 MDB 파일과 매우 호환됩니다. Access 2010에서는 지원되지 않는 것 같지만 실제로는 기능이 숨겨져 있지만 매우 잘 지원됩니다. MDE와 마찬가지로 ADP 파일은 ADE 파일로 "컴파일"될 수 있습니다.

SQL Server로 마이그레이션하면 데이터 구조와 코드를 거의 수정하지 않아도되지만 모두 마이그레이션하기가 쉽습니다. 그리고 그것은 결국 최종 목표입니다.

VBA 또는 VB.Net 코드로 데이터베이스 이벤트를 트리거하는 것을 잊어 버리십시오. 이것은 기술적으로 SQL Server 확장 저장 프로 시저를 사용하여 수행 할 수 있지만 매우 나쁜 트릭입니다. 프로젝트는 미래의 수명을 가지므로 이러한 종류의 파괴적인 다리를 피함으로써 데이터 구조를 적용하는 것이 좋습니다. 일반적으로 데이터베이스 트리거로 재생하면 영리하지만 유지 관리하기가 어렵습니다.

2 단계 : 인증 균일화

응용 프로그램이 액세스 보안 (MDW 파일)을 기반으로하지 않는 것이 좋습니다.

VB.Net 애플리케이션의 대상 인증 계획을 작성한 후 두 애플리케이션간에 균일 한 인증을 얻기 위해 액세스 인증을이 대상으로 마이그레이션하는 방법을 정의하십시오.

인증은 응용 프로그램 아키텍처에서 가로 지르기 때문에 Access 버전과 VB.Net 버전간에 더 쉽게 슬라이스 할 수 있습니다.

3 단계 : Access와 VB.Net을 연결하기위한 토큰 기능 준비

액세스 UI는 정확한 매개 변수와 인증을 통해 VB.Net UI를 열어야합니다. 그리고 다른 방법으로도 똑같이해야 할 것입니다.

좋은 해결책은 토큰 테이블을 기반으로 작은 토큰 기능을 작성하는 것입니다. 열은 토큰 ID (정수), 토큰 키 (긴 문자열), 토큰 날짜 및 매개 변수 목록 (긴 문자열 또는 텍스트) 일 수 있습니다. Access에서 VB.Net 화면을 열어야 할 때마다 매개 변수를 사용하여 데이터베이스에 토큰을 저장 한 다음 토큰 ID와 토큰 키만으로 VB.Net 응용 프로그램을 엽니 다. VB.Net이 열리고 데이터베이스에서 토큰 ID를 검색하고 키 (인증으로 적용됨)를 확인한 후 매개 변수를 읽습니다. 그런 다음 해당 양식을 열고 필요한 작업을 수행하십시오. 토큰 지속 시간을 제공하고 오래된 토큰을 정리하는 것을 잊지 마십시오.

VB.Net에서 Access로 콜백 해야하는 경우 (아마도) OLE를 사용하여 열린 MDB Access 파일에서 일부 VBA 코드를 활성화 할 수 있다고 생각합니다.

4 단계 : UI 별 및 모듈 별 화면 별, 모듈 별 마이그레이션

이제 큰 준비가 완료되었습니다. Ms Access에서 VB.Net으로 사용자 인터페이스 마이그레이션을 시작할 수 있습니다.

이를위한 좋은 자동 도구는 없습니다. VBA와 .Net이 너무 다릅니다. 이러한 마이그레이션을 위해 작업을 준비해야합니다. "정보"상자와 같은 작은 양식으로 시작하여 간단한 양식에서 복잡한 양식으로 계속하십시오. 물론 일부 마이그레이션을 번들로 만들어 예약해야하지만 화면, 보고서 및 라이브러리를 Ms Access에서 VB.Net으로 점차 마이그레이션합니다.


1

Access를 통해 모든 작업을 수행 한 것에 놀랐습니다. .NET Windows Forms 또는 .NET WPF를 요구하지 않는 매우 중요한 질문이 있습니다. WPF는 가파른 학습 곡선을 가지고 있지만 더 나은 UI를 사용하면 더 강력합니다. 최근 상용 응용 프로그램을 Forms에서 WPF로 변환했으며 이미 더 많은 판매를 받고 있습니다. 우리는 또한 새로운 기능을 추가했지만 WPF UI는 더 섹시합니다. 테이블 디자인을 검토하고 정리하십시오. 이제 시간입니다. FK를 모두 신고해야합니다. Access에서 당신은 물건을 미끄러지는 몇 번이나 쉽게 물건을 추가 할 수 있습니다. 이것이 첫 번째 WPF UI 인 경우 일부 프로토 타입을 빌드하십시오. 새로운 앱에 더 많은 기능, 화면 및 코드가 적다는 것을 WPF에 더 많이 담을 수 있습니다. XAML을 싫어하는 것부터 그것을 사랑하는 방법으로 갈 것입니다. MVVM과 같은 구조를 고려하십시오.


우리는 WinForms, WPF 및 Silverlight (RIA 및 브라우저 외부 둘 다)를 사용하여 여러 개의 작은 .Net 응용 프로그램을 개발했으며 WPF (및 Silverlight)가 응용 프로그램에 대해 훨씬 더 섹시한 모양과 느낌을 제공한다는 데 동의합니다.
Alexander Galkin

0

Access 개체 모델에 대해 이미 잘 알고 있으므로 .NET 앱에서 Access Interop 을 사용하고 싶다고 생각합니다 . DDE의 불투명성없이 Access 앱 제어를 자동화 할 수 있어야합니다.


이것이 좋은 생각이라고 생각하지만 이전 버전의 Access를 사용하는 경우 필요한 기능 수준이 없을 수 있습니다.
jfrankcarr

-1

비즈니스 논리 계층에 대한 깊은 지식은 없지만 .NET 응용 프로그램에서 MS Access 데이터베이스에 액세스 할 수도 있습니다. 단순히 데이터를 가져 오는 것이 아니라면 프로그램 (VB6 및 VB.NET 응용 프로그램)간에 TCP / IP 연결을 구현할 수 있습니다. CodeProject대한 기사를 살펴보십시오 .


"...이 응용 프로그램과 실행중인 MS Access 응용 프로그램간에 데이터 교환을 활성화하십시오." 그 진술이 내 대답과 관련이 없다면 그렇다면 나는 아무것도 모른다.
Osman Turan

승인. 사과드립니다. 공감 비가 제거되었습니다.
Arseni Mourzenko

@MainMa : 문제 없습니다.
Osman Turan

1
제 답변은 편집 후에도 여전히 유효합니다. 나는 두 가지 방법에 대해 언급했다. 그중 하나는 편집 후 쓸모없는 것으로 드러난 직접 액세스이며 다른 하나는 N-Tier 응용 프로그램입니다. 응용 프로그램 사이에 TCP / IP 프로토콜을 구현해야한다고 생각합니다. 같은 컴퓨터에서 응용 프로그램을 실행하려는 경우에도이 방법을 사용하는 것이 좋습니다. 이전 경험에서 DDE가 그러한 용도에 대해 매우 신뢰할 수 없으며 실제로 성가신 것으로 나타났습니다. 로컬 응용 프로그램에 대한 또 다른 접근 방식은 사용자 지정 시스템 메시지 (창 메시지)를 사용하는 것입니다.
Osman Turan

1
내 생각보다 큰 문제가있는 것 같습니다. MSMQ BTW에 익숙하지 않습니다. 죄송합니다.
Osman Turan

-1

잘못된 일을하는 방법에 대한 모범 사례를 요구하고 있습니다. 하나도 없습니다. 모범 사례에는 유지 보수 가능한 시스템을 효과적으로 작성하는 방법이 포함되므로 버스가 충돌하고 완전히 새로운 팀이 식어야하더라도 개발 및 지원을 계속할 수 있습니다. 당신이 설명하는 시스템은 언덕을 향해 달리는 대부분의 개발자를 보낼 것입니다. 더 이상 사용되지 않는 기술로 제작 된 제품이 있으며 오늘날의 기술과 인터페이스하고 싶습니다. 그리고 핵심 제품에 대해 설명한 안티 패턴을 해결하지 않고도 그렇게 할 수 있습니다. 문제를 해결하고자하는 개발자는 귀하가 제안한 조건으로는 그렇게하지 않을 것입니다.

그러나 버스가 고장 나지 않아 시스템을 이해하는 기존 팀을 활용할 수 있습니다. 내가 찾은 점진적으로 발전하는 가장 좋은 방법은 애자일 방법론을 사용하는 것입니다. 초기에 높은 위험 요구 사항을 해결하고 비즈니스 요구를 잘 해결하는 반복 프로세스를 지원합니다.


-2

애플리케이션을 .Net으로 점차 이동하기로 결정했습니다.

종종 실수입니다. 모범 사례는 "점진적으로"시도하지 않는 것입니다.

이곳은 대부분의 개발자에게 새로운 언어이지만 VBA와 VB6에서 구현 된 수십 개의 소규모 프로젝트에 대한 깊은 지식을 가지고 있습니다.

결정을위한 좋은 근거는 아닙니다. 새로운 언어를 배우고 싶다면 VB를 배우지 마십시오. C #이나 Java와 같은 것을 배우십시오.

"여기에있는 대부분의 개발자를위한 새로운 언어, VBA에 대한 깊은 지식이 있습니다"는 "우리가 짜증나고 싶지 않은 VBA 전문가가 있습니다"라는 일반적인 코드 문구입니다. 그것은 또한 나쁜 일입니다.

우리가 찾고있는 것은 광범위한 GUI를 점진적으로 이동시키는 모범 사례입니다

모범 사례에는 "Gradual"이 포함되지 않습니다. 여기에는 "완전히 폐기"가 포함됩니다.

내가 본 점진적인 마이그레이션은 너무 어렵 기 때문에 세분화되었습니다.

이 작업을 수행하는 것이 좋습니다.

  1. 가장 귀중한 자산을 보존하십시오 . 자료. 모든 데이터를 SQL Server로 이동하십시오. 그것의 모든. SQL Server에 대한 ODBC 연결을 사용하려면 모든 MS-Access를 다시 작성하십시오. 지금.

  2. MS-Access에서 임시 테이블이나 데이터 또는 무언가를 만드는 사람을 해고하십시오. 모든 데이터는 MS-Access 외부의 데이터베이스에 있어야합니다. MS-Access의 데이터가 문제의 원인이므로 지금 중지하고 모든 사람이 동의하는지 확인하십시오. 그들이 동의하지 않으면 MS-Access를 제거하려고 시도하는 동안 MS-Access에서 해킹을 포함하지 않는 새로운 직업을 찾으십시오.

  3. 현재 가지고있는 것에 가까운 보고서를 자동으로 생성하는보고 프레임 워크를 찾으십시오. 프로그래밍이 없습니다. 그냥 테이블이나 뷰를 제공하고 쾅! 끝났다.

  4. 500 개의 보고서를 모두 열거하십시오. 도구를 사용하여 쉽게 작성할 수있는 보고서와 어려운 보고서로 분할하십시오. 어려운 사람을 "필수 항목", "필수 항목", 가질 수 있음 "및"나중에하지 말아야 할 항목 "으로 우선 순위를 지정하십시오. 자동화 된 보고서와 필수 보고서를 MS-Access 외부에서 완전히보고해야합니다.

    내 경험은 데이터베이스 뷰가 종종 약 20여 개의 보고서에서 재사용된다는 것입니다. 이를 통해 500 개의 보고서가 도출되는 25 개의 관련보기가 있다고 생각합니다. 보고서 작성을 자동화 할 수있는 모든 도구는 소규모의 잘 만들어진 SQL보기 세트에서 대부분의 보고서를 처리해야합니다. 자동화 된 도구로는 보고서가 너무 복잡하거나 어려울 수 있습니다.

  5. CRUD 트랜잭션을 자동으로 빌드하는 개발 프레임 워크를 찾으십시오.

  6. 200 개의 양식을 CRUD 양식 (자동으로 작성 가능)과 CRUD가 아닌 양식으로 분할하십시오. 비 CRUD 중에서 MoSCoW (Must, should, Could, Wo n't) 규칙을 사용하여 우선 순위를 정하십시오.

    종종 신청서 양식의 60-80 %가 단순하고 자동화 된 CRUD 양식입니다. 20-40 %는 더 복잡하고 더 숙련 된 프로그래밍이 필요합니다. 이를 바탕으로 120 ~ 160 개의 CRUD 양식을 다시 작성할 필요가 없으며 자동화하면됩니다. 40-80 개의 매우 복잡한 트랜잭션이 있습니다.

  7. CRUD 양식과 CRUD가 아닌 필수 양식을 작성하십시오.

  8. 격차를 평가하십시오. "Should-Have"목록의 가장 중요한 부분에 대해 우선 순위를 정하고 작업을 시작하십시오.

Access를 완전히 버리는 것이 가장 쉬운 방법 일 것입니다. 점 진주의를 피하십시오.

당신은 결국 모든 돈을 쓸 것입니다.

당신은 또한 그것을 위해 예산을 책정하고 지금 쓸 수 있습니다.

공존 관리의 복잡성으로 인해 점진적으로이 작업을 수행하면 비용 이 많이들 수 있습니다 .


9
이것은 모두 훌륭하지만 현실적이지는 않습니다. 특히 "누군가를 해고"와 "완전히 버리는"부분. 우리는 모든 것을 버릴 수 없으며 재무, 전략 및 개인적 관점 모두에서 녹색 분야에서 시작할 수 없습니다.
Alexander Galkin

8
-1 당신의 경험은 우주의 합계가 아닙니다. 우리 모두는 현실이 아닌 문화를 즉시 바꿀 수있는 완벽한 세상에서 살고 싶어합니다. 또한 일부 입증 된 기술에 대한 편견은 다른 잠재적 인 솔루션을 볼 수있는 능력을 흐리게합니다. OP가 아닌 문제를 해결하는 가장 좋은 방법을 설명했습니다.
SoylentGray

4
종종 실수 로 -1이되어 죄송합니다 . 모범 사례는 "점진적으로"시도하지 않는 것입니다. -이 '모범 사례'에 대한 인용이 있습니까? 대부분의 사람들이 반대말을하기 때문에 – joelonsoftware.com/articles/fog0000000069.html
MattDavey

2
"대부분의 사람들은 그 반대라고 말할 것입니다". 대부분의 사람들은 내가 함께 일했던 고객보다 똑똑합니다. 그들에게 좋습니다. 슬프게도, 나는 점차적으로 마이그레이션 할 수 없기 때문에 도매 재 작성이 필요한 크고 나쁜 MS-Access 응용 프로그램을 사용하는 많은 고객과 협력해야했습니다. 내 경험이야 저의 인용입니다. 내 경험이 독창적 인 것 같습니다.
S.Lott

4
@ S.Lott 코드가 가치보다 더 책임이 있다고 말하는 것이 극단적이라고 생각합니다. OP가 말한 바에 따르면 작동하지 않거나 비즈니스 요구를 충족시키지 못했다는 사실은 사실이다. "우리는 현재 응용 프로그램의 현재 기능에 매우 만족하고 있습니다. " 완벽하게 작동하는 코드를 저장해야 할 긴급한 필요는없는 것 같습니다. 그러나 OP는 향후 개선을 위해 Access가 부과 한 유리 천장을 돌파해야한다는 점을 확인했습니다. 이는 점진적인 프로세스 일 수 있습니다.
MattDavey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.