Cách chúng tôi tự động di chuyển SQL Server sang Java và tăng tốc gấp 4 lần
Bài viết này dành riêng cho việc hiện đại hóa Microsoft SQL Server dựa trên một dự án do Ispirer thực hiện cho một công ty lớn hoạt động trong lĩnh vực tư vấn tài chính. Khách hàng đã khai thác sức mạnh của cơ sở dữ liệu SQL Server để xử lý, xử lý, truy cập và giám sát thông tin tài chính của khách hàng một cách hiệu quả. Máy khách nhằm mục đích di chuyển SQL Server sang đám mây đồng thời tối ưu hóa kiến trúc hệ thống và chi phí bảo trì.
Nhóm Ispirer đã đề xuất chuyển logic nghiệp vụ sang Java vì cơ sở dữ liệu được sử dụng ở chế độ OLTP. Chúng tôi sẽ phân tích cẩn thận chủ đề và xem xét dự án của khách hàng, bao gồm việc chuyển đổi các quy tắc kinh doanh của SQL Server sang Java. Ngoài ra, chúng tôi sẽ điều tra lý do đằng sau việc các công ty chọn di chuyển mã SQL sang lớp ứng dụng. Điều này sẽ liên quan đến việc kiểm tra toàn diện toàn bộ quá trình.
Để tối ưu hóa chi phí của cơ sở hạ tầng đám mây, khách hàng đã quyết định di chuyển bảng và dữ liệu sang PostgreSQL. Vì chúng tôi chuyên về di chuyển cơ sở dữ liệu và ứng dụng nên khách hàng đã tìm đến chúng tôi với các nhiệm vụ sau:
- Di chuyển 815000 LỘC logic nghiệp vụ sang lớp ứng dụng trong Java.
- Di chuyển 300 GB dữ liệu và 3000 bảng từ Microsoft SQL Server sang PostgreSQL.
Do quy mô đáng kể của dự án, khách hàng đã nỗ lực giảm thiểu chi phí di chuyển bằng cách triển khai tự động hóa. Để tối ưu hóa hiệu quả của Bộ công cụ Ispirer, chúng tôi xác định rằng việc tùy chỉnh nó phải được tiến hành trước. Cách tiếp cận này cho phép chúng tôi cung cấp một công cụ cho nhóm của khách hàng, với tỷ lệ chuyển đổi T-SCL sang Java xấp xỉ 90%.
Bây giờ chúng ta hãy tìm hiểu sâu hơn về việc di chuyển bảng và dữ liệu.
Từ SQL Server sang PostgreSQL: di chuyển dữ liệu và bảng
Hãy xem xét lý do tại sao khách hàng chọn di chuyển từ Máy chủ SQL tại chỗ sang đám mây. Quá trình chuyển đổi này bao gồm một số lợi thế không thể phủ nhận:
- Tiết kiệm chi phí. Một trong những yếu tố thúc đẩy chính đằng sau việc di chuyển từ SQL Server sang PostgreSQL trên đám mây là tiết kiệm chi phí. Khách hàng từng thấy việc lưu giữ cơ sở dữ liệu SQL Server tại chỗ rất tốn kém. Điều này là do nhu cầu về thiết bị đặc biệt, giấy phép phần mềm và quản trị viên cơ sở dữ liệu có tay nghề cao. PostgreSQL, là cơ sở dữ liệu nguồn mở, cung cấp giải pháp thay thế hiệu quả về mặt chi phí. Khách hàng có thể tiết kiệm tiền bằng cách sử dụng đám mây. Họ chỉ phải trả tiền cho những gì họ sử dụng, thay vì trả trước những khoản lớn. Ngoài ra, họ có thể chi tiêu ít hơn cho hoạt động.
- Khả năng mở rộng. Điện toán đám mây có thể mở rộng quy mô dễ dàng hơn cơ sở hạ tầng tại chỗ để phục vụ khối lượng công việc lớn hơn và nhiều người dùng hơn. Để hệ thống tại chỗ có thể mở rộng quy mô theo nhu cầu của doanh nghiệp, các tổ chức phải mua và cài đặt máy chủ vật lý, giấy phép phần mềm, bộ lưu trữ và thiết bị mạng để mở rộng quy mô dịch vụ kinh doanh trong cài đặt CNTT thông thường. Trên đám mây, hầu hết các tài nguyên này đều có sẵn ngay lập tức chỉ sau vài cú nhấp chuột và có thể tự động tăng giảm quy mô tùy thuộc vào tài nguyên cần thiết. PostgreSQL trên đám mây cung cấp khả năng mở rộng ở mức độ cao, cho phép khách hàng của chúng tôi dễ dàng điều chỉnh tài nguyên dựa trên nhu cầu.
- Bảo vệ. Sử dụng công nghệ đám mây mang lại những lợi thế bảo mật đáng chú ý nhờ các hệ thống kiểm soát nhận dạng, quản lý quyền truy cập và xác thực nâng cao do các nhà cung cấp đám mây cung cấp. Thông thường, các nhà cung cấp đám mây có tiêu chuẩn bảo mật tốt hơn các nhóm CNTT nội bộ hoặc hệ thống cục bộ, giúp môi trường dữ liệu an toàn hơn. Mã hóa mạnh mẽ trên đám mây giúp giảm nguy cơ vi phạm dữ liệu. Nó bao gồm bảo mật nhiều lớp, quản lý khóa tốt và kiểm soát truy cập an toàn, giúp doanh nghiệp kiểm soát quyền truy cập của người dùng một cách hiệu quả. Hơn nữa, các nhà cung cấp đám mây giám sát chặt chẽ việc truy cập vật lý, thực hiện các biện pháp như ẩn danh, sao chép và mã hóa để tăng cường bảo vệ dữ liệu. Đến năm 2025, dự đoán khoảng sẽ chuyển đổi từ trung tâm dữ liệu vật lý sang dịch vụ đám mây. Sự thay đổi này được thúc đẩy bởi các lợi ích bảo mật nâng cao do đám mây cung cấp.
Việc chuyển từ SQL Server sang PostgreSQL trên đám mây đòi hỏi phải lập kế hoạch và thực hiện cẩn thận, có lưu ý đến những cân nhắc cụ thể. Dựa trên dự án của khách hàng, nhóm của chúng tôi đã nêu bật các bước sau để hiện đại hóa SQL Server:
- Lược đồ và chuyển đổi dữ liệu. Dữ liệu phải được chuyển đổi chính xác để phù hợp với yêu cầu của PostgreSQL. Điều này có thể liên quan đến việc xử lý các sắc thái như định dạng ngày tháng và mã hóa ký tự.
- Những ràng buộc và kích hoạt. Hiểu được sự khác biệt trong việc sử dụng các ràng buộc và kích hoạt trong hai cơ sở dữ liệu là rất quan trọng. Cần phải thực hiện những sửa đổi cần thiết cho phù hợp. Ngoài ra, chức năng của trình kích hoạt có thể được chuyển vào ứng dụng. Tuy nhiên, nhiệm vụ này không hề đơn giản nên việc cân nhắc những ưu và nhược điểm là điều cần thiết.
- Tối ưu hóa hiệu suất. Tối ưu hóa quá trình di chuyển cho phép giảm thiểu thời gian ngừng hoạt động và thời gian truyền dữ liệu. Điều quan trọng là tận dụng khả năng song song hóa, tối ưu hóa băng thông mạng và đầu tư vào phần cứng mạnh mẽ để di chuyển hiệu quả
- Xác thực và kiểm tra dữ liệu. Cần phải xác thực nghiêm ngặt dữ liệu được di chuyển để đảm bảo tính toàn vẹn và chức năng của dữ liệu. Thử nghiệm mở rộng đảm bảo rằng các ứng dụng hoạt động liền mạch với cơ sở dữ liệu PostgreSQL mới.
- Bảo mật và quyền. Cài đặt bảo mật, tài khoản người dùng và quyền trong PostgreSQL phải được định cấu hình để phù hợp với thiết lập SQL Server ban đầu, đảm bảo quá trình chuyển đổi liền mạch.
Tại sao phải chuyển logic nghiệp vụ sang Lớp ứng dụng?
Trước đây, khách hàng của chúng tôi sử dụng các quy trình được lưu trữ cho logic kinh doanh của họ vì nghĩ rằng nó sẽ cải thiện hiệu suất. Nhưng thành thật mà nói, ngôn ngữ SQL có thể không phải là lựa chọn tối ưu để chứa logic nghiệp vụ khi so sánh với lớp ứng dụng. Trên thực tế, SQL chỉ truy vấn hoặc sửa đổi dữ liệu trong cơ sở dữ liệu. Ở đây, nhiều người có thể ném cà chua thối vào chúng tôi, vì ngôn ngữ SQL rất giỏi thực hiện các phép nối, lọc và sắp xếp phức tạp để lấy chính xác dữ liệu bạn cần từ một truy vấn và không làm gì khác. Vậy thì tại sao phải thay đổi bất cứ điều gì và đưa logic nghiệp vụ lên cấp độ ứng dụng? Câu hỏi có vẻ logic. Hãy trả lời nó chi tiết hơn. Dưới đây chúng tôi đã nêu ra 4 lý do chính khiến bạn nên suy nghĩ nghiêm túc về việc chuyển logic nghiệp vụ sang ứng dụng. Quyết định của khách hàng trong việc chuyển logic nghiệp vụ sang lớp ứng dụng được thúc đẩy bởi các lý do sau:
Khả năng mở rộng
Về khả năng mở rộng, việc lưu trữ logic nghiệp vụ ở cấp ứng dụng là lựa chọn tốt nhất. Tại sao? Bởi vì, nói chung, việc mở rộng quy mô tài nguyên máy chủ ứng dụng của bạn về cơ bản dễ dàng hơn so với việc mở rộng quy mô tài nguyên máy chủ cơ sở dữ liệu. Điều này gần như được thừa nhận rộng rãi. Đối với hầu hết các ứng dụng web, việc thêm nhiều máy chủ thường dễ dàng khi có nhiều lưu lượng truy cập cần xử lý. Tuy nhiên, giá trị của các máy chủ ứng dụng bổ sung sẽ giảm đi trừ khi cơ sở dữ liệu của bạn cũng có thể mở rộng quy mô để đáp ứng nhu cầu gia tăng. Việc mở rộng quy mô máy chủ cơ sở dữ liệu khó khăn hơn đáng kể so với việc chỉ thêm máy chủ ứng dụng.
Khả năng bảo trì
Việc lưu trữ logic nghiệp vụ trong cơ sở dữ liệu có thể tạo ra những thách thức về khả năng bảo trì. Việc sửa đổi các thủ tục được lưu trữ có thể làm gián đoạn nhiều ứng dụng, hạn chế khả năng mở rộng và khiến việc tuân theo nguyên tắc "Đừng lặp lại chính mình" (DRY) trở nên khó khăn. Mã SQL vượt quá 100 dòng thường gây ra sự phức tạp và khó khăn khi khắc phục sự cố. Việc tách logic nghiệp vụ thành tầng ứng dụng có thể tạo điều kiện thuận lợi cho các thành viên mới trong nhóm tham gia và cung cấp nền tảng tái cấu trúc trực quan hơn.
Dễ dàng phát triển
SQL là một lựa chọn tồi để mã hóa các quy tắc kinh doanh trong hệ thống của bạn. Nó không linh hoạt và chúng ta không thể dựa vào nó để biểu diễn các mô hình phức tạp vì nó không thể tạo ra sự trừu tượng phù hợp. Hạn chế này là lý do chính để tránh sử dụng nó cho logic nghiệp vụ. Vấn đề không phải là về công cụ hay hỗ trợ, mà là về việc SQL không có khả năng tạo ra một mô hình miền đơn giản và biểu cảm, trái ngược với thiết kế hướng đối tượng và chức năng vốn mang lại nhiều cơ hội hơn.
Khả năng tái sử dụng
Trong phát triển phần mềm, sử dụng lại mã là một cách hiệu quả để tiết kiệm thời gian và chi phí khi điều chỉnh mã hiện có cho các tác vụ mới. Lập trình hướng đối tượng (OOP) là một phương pháp hỗ trợ tái chế mã, làm cho nó phù hợp với nhiều ứng dụng khác nhau. Tuy nhiên, SQL, thường được sử dụng trong cơ sở dữ liệu, cung cấp tính linh hoạt hạn chế cho việc sử dụng lại mã. Các tùy chọn bao gồm sử dụng "chế độ xem" và "thủ tục được lưu trữ", mặc dù tùy chọn sau có thể dẫn đến nhiều tham số. Để đảm bảo lựa chọn đúng đắn cho dự án của bạn, việc khám phá kỹ lưỡng từng phương pháp là điều cần thiết.
Chuyển đổi Transact-SQL sang Java
Việc chuyển đổi Transact-SQL sang Java bao gồm nhiều cân nhắc cần thiết khác nhau. Quá trình này bao gồm việc ánh xạ các kiểu dữ liệu SQL sang các kiểu dữ liệu Java tương đương, đảm bảo việc biểu diễn dữ liệu chính xác. Nó cũng bao gồm việc dịch các truy vấn SQL sang mã Java, trong đó Java dựa vào các thư viện như JDBC hoặc Hibernate để xử lý các tương tác cơ sở dữ liệu. Hơn nữa, một số tính năng ESQL nhất định thiếu các tính năng tương đương trực tiếp trong Java, có khả năng gây ấn tượng rằng việc chuyển đổi tự động là không hiệu quả. Trong giai đoạn tùy chỉnh của dự án, chúng tôi có thể tạo một số giải pháp chuyển đổi giúp nâng cao tỷ lệ tự động hóa. Những giải pháp này ban đầu được cho là không thể tự động hóa nhưng cuối cùng lại tỏ ra thành công. Hãy đi sâu vào chi tiết của một số trong số họ.
- Chuyển đổi câu lệnh INSERT kết hợp với SCOPE_IDENTITY() để lấy giá trị nhận dạng cuối cùng được chèn vào cột nhận dạng. Nguồn:
ALTER PROCEDURE example1 AS BEGIN Declare @idBit int Declare @c int Insert Into tab (c) Values (@c) Set @idBit = SCOPE_IDENTITY() End
Mục tiêu:
@Service public class Example1 implements IExample1 { @Autowired private JdbcTemplate jdbcTemplate; private static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(Example1.class); @Override public Integer spExample1() throws SQLException, Exception { Integer mStatus = 0; KeyHolder keyHolder = new GeneratedKeyHolder(); try { Integer idBit = null; Integer c = null; { final Integer tmpC = c; jdbcTemplate.update(connection-> { PreparedStatement ps = connection.prepareStatement("Insert Into tab(c) \r\n" + " Values(?)", new String[] { "" }); ps.setInt( 1, tmpC); return ps; }, keyHolder); } idBit = Tsqlutils.<Integer > strToNum(keyHolder.getKey().toString(), Integer.class); return mStatus; } catch (Exception e) { LOGGER.error(String.valueOf(e)); mStatus = -1; return mStatus; } } }
- Chuyển đổi thủ tục với nhiều Bộ kết quả.
Nguồn:
ALTER PROCEDURE [returnSeveralResultSet] @p1 int, @p2 varchar(50) AS Begin select cob_ft, lower(buzon) from tab1 where cob_id = @p1 and cob_ft = @p2 select dep_ft, lower(fiton) from tab2 END
Mục tiêu:
@Service public class Returnseveralresultset implements IReturnseveralresultset { @Autowired private JdbcTemplate jdbcTemplate; private static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(Returnseveralresultset.class); private Integer errorCode = 0; private String sqlState = ""; @Override public Map<String, Object> spReturnseveralresultset(Integer p1, String p2) throws Exception { Integer mStatus = 0; Map<String, Object> outData = new HashMap<>(); List<SqlRowSet> outRsList = new ArrayList<>(); SqlRowSet rowSet; try { rowSet = jdbcTemplate.queryForRowSet("select cob_ft, lower(buzon) from tab1 \r\n" + " where cob_id = ? and cob_ft = ?", p1, p2); outRsList.add(rowSet); rowSet = jdbcTemplate.queryForRowSet("select dep_ft, lower(fiton) from tab2"); outRsList.add(rowSet); return outData; } catch (Exception e) { LOGGER.error(String.valueOf(e)); mStatus = -1; return outData; } finally { outData.put("status", mStatus); outData.put("rsList", outRsList); } } }
- Chuyển đổi phương pháp DATEDIFF. Vì Java không có phương thức tương đương trực tiếp nên nhóm Ispirer đã phát triển một phương thức tương đương với phương thức này để chuyển Chuỗi thành Dấu thời gian mà không có định dạng được chỉ định rõ ràng. Nó làm cho kết quả mã gọn gàng và dễ đọc hơn. Ví dụ dưới đây minh họa cách nó được sử dụng.
Nguồn:
create procedure datediffFn as declare @var1 int set @var1 = DATEDIFF(dd, '1999-01-01', '2000-02-01') set @var1 = DATEDIFF(mm, getdate(), '2000-02-01') set @var1 = DATEDIFF(week, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
Mục tiêu:
public Integer spDatedifffn() throws Exception { Integer mStatus = 0; try { Integer var1 = null; var1 = Tsqlutils.datediff("dd", Tsqlutils.toTimestamp("1999-01-01"), Tsqlutils.toTimestamp("2000-02-01")); var1 = Tsqlutils.datediff("mm", new Timestamp(new java.util.Date().getTime()), Tsqlutils.toTimestamp("2000-02-01")); var1 = Tsqlutils.datediff("week", Tsqlutils.toTimestamp("2005-12-31 23:59:59.9999999"), Tsqlutils.toTimestamp("2006-01-01 00:00:00.0000000")); return mStatus; } catch (Exception e) { LOGGER.error(String.valueOf(e)); mStatus = -1; return mStatus; } }
- Chuyển đổi phương thức sp_send_dbmail để gửi tin nhắn e-mail đến người nhận được chỉ định. Với mục đích này, một lớp có tên MailService đã được phát triển. Phương pháp này cho phép gửi email với thông số kỹ thuật chi tiết, bao gồm người nhận (TO), người nhận bản sao (CC), người nhận trong bản sao ẩn (BCC), chủ đề của bức thư, văn bản chính, tệp đính kèm, v.v. . Để giữ cho mã chính gọn gàng, nhóm của chúng tôi đã đặt phương thức này vào một lớp riêng.
Nguồn:
create PROCEDURE spSendDbmail AS BEGIN EXEC msdb.dbo.sp_send_dbmail @profile_name = 'New DB Ispirer Profile', @recipients = '[email protected]', @body = '<h1>This is actual message embedded in HTML tags</h1>', @subject = 'Automated Success Message' , @file_attachments = 'C:\Temp\Attached.txt', @body_format='HTML', @copy_recipients = '[email protected]', @blind_copy_recipients = '[email protected]'; END
Mục tiêu:
import java.util.*; import com.ispirer.mssql.mail.MailService; public class Spsenddbmail { private static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(Spsenddbmail.class); public Integer spSpsenddbmail() throws Exception { Integer mStatus = 0; try { MailService.send("New DB Ispirer Profile", "Automated Success Message", "<h1>This is actual message embedded in HTML tags</h1>", "[email protected]", "[email protected]", "[email protected]", "C:\\Temp\\Attached.txt", "HTML"); return mStatus; } catch (Exception e) { LOGGER.error(String.valueOf(e)); mStatus = -1; return mStatus; } } }
- Nhóm Ispirer đã phát triển một lớp XMLUtils để chuyển đổi kiểu Dữ liệu xml và các phương thức của nó, được sử dụng để lấy bất kỳ thông tin nào từ dữ liệu XML được lưu trữ trong một biến XML. Một ví dụ thực hiện phương pháp:
Nguồn:
create procedure workWithXml AS begin declare @result bit, @myDoc XML, @myStr varchar(1000), @ProdID INT SET @myDoc = '<Root> <ProductDescription ProductID="1" ProductName="Road Bike"> <Features> <Warranty>1 year parts and labor</Warranty> <Maintenance>3 year parts and labor extended maintenance is available</Maintenance> </Features> </ProductDescription> </Root>' SET @result = @myDoc.exist('(/Root/ProductDescription/@ProductID)[1]') SET @myStr = cast(@myDoc.query('/Root/ProductDescription/Features') as varchar(max)) SET @ProdID = @myDoc.value('(/Root/ProductDescription/@ProductID)[1]', 'int' ) end;
Mục tiêu:
import java.util.*; import com.ispirer.mssql.xml.XMLUtils; public class Workwithxml { private static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(Workwithxml.class); public Integer spWorkwithxml() throws Exception { Integer mStatus = 0; try { Boolean result = null; String myDoc = null; String myStr = null; Integer prodID = null; myDoc = "<Root> " + "<ProductDescription ProductID=\"1\" ProductName=\"Road Bike\"> " + "<Features> " + "<Warranty>1 year parts and labor</Warranty> " + "<Maintenance>3 year parts and labor extended maintenance is available</Maintenance> " + "</Features> " + "</ProductDescription> " + " </Root>"; result = XMLUtils.exist(myDoc, "(/Root/ProductDescription/@ProductID)[1]"); myStr = XMLUtils.query(myDoc, "/Root/ProductDescription/Features"); prodID = XMLUtils.<Integer > value(myDoc, "(/Root/ProductDescription/@ProductID)[1]", Integer.class); return mStatus; } catch (Exception e) { LOGGER.error(String.valueOf(e)); mStatus = -1; return mStatus; } } }
Nhờ những nỗ lực tùy chỉnh, nhóm của chúng tôi đã phát triển thành công nhiều kỹ thuật để tự động hóa quá trình chuyển đổi từ T-SQL sang Java. Điều này đã giảm đáng kể thời gian di chuyển tổng thể cho toàn bộ dự án, cho phép chúng tôi tăng tốc quá trình di chuyển gấp 4 lần so với khả năng di chuyển thủ công. Việc tùy chỉnh Bộ công cụ của chúng tôi không chỉ đẩy nhanh quá trình chuyển đổi mà còn nâng cao hiệu quả tổng thể của dự án, cho thấy tác động có giá trị của các sáng kiến tùy chỉnh của chúng tôi. Các phương pháp được chỉ định trong ví dụ được cung cấp cho khách hàng cùng với kết quả chuyển đổi.
Phần kết luận
Tóm lại, việc chuyển đổi logic nghiệp vụ từ Transact-SQL sang Java là một quá trình nhiều mặt đòi hỏi sự hiểu biết toàn diện về cả hai ngôn ngữ và các tính năng riêng biệt của chúng.
Trong bài viết này, chúng tôi đã khám phá kỹ lưỡng quá trình di chuyển logic nghiệp vụ sang lớp ứng dụng và cung cấp thông tin chi tiết có giá trị cho những ai đang lên kế hoạch chuyển đổi như vậy. Trường hợp của khách hàng của chúng tôi chứng minh rằng các dự án hiện đại hóa như vậy có thể được tự động hóa, giúp tiết kiệm đáng kể thời gian và công sức trong quá trình di chuyển. Dự án của khách hàng của chúng tôi là minh chứng thuyết phục cho tiềm năng vượt trội của tự động hóa. Nó chứng tỏ rằng có những khía cạnh hiện đại hóa trong đó tự động hóa có thể hợp lý hóa thành công các quy trình mà ban đầu có thể vượt quá khả năng của nó.
Cuối cùng, việc chuyển đổi từ Transact-SQL sang Java là một bước đi chiến lược dành cho các tổ chức đang tìm kiếm tính linh hoạt cao hơn, khả năng tương thích đa nền tảng và khả năng mở rộng. Mặc dù nó đưa ra những thách thức nhưng lợi ích về tính di động, hiệu suất và khả năng thích ứng với các kiến trúc phần mềm hiện đại khiến quá trình chuyển đổi này trở thành một nỗ lực đáng giá cho những ai muốn hiện đại hóa các ứng dụng và hệ thống cơ sở dữ liệu của họ.