Có nên xử lý, thay đổi dữ liệu trực tiếp trên database?

Anh chị cho em hỏi:

  • Có nên xử lý dữ liệu (update, create, delete…) trực tiếp trên database thông qua câu lệnh của ngôn ngữ đang lập trình không?

Câu hỏi hơi khó hiểu, ví dụ như lúc trước em có làm bài tập lớn ứng dụng quản lý nhân viên quán cà phê bằng C#, làm database bằng SQL server. Khi load form lên thì em nạp dữ liệu từ cái database của SQL server vào từng class NhanVien bằng mảng hoặc Arraylist, xong em thao tác trên mảng đã tạo đó, cuối bài đóng form thì save mảng đó vào lại database.

Nhưng em thấy nhiều đứa bạn không tạo class mà thao tác trực tiếp trên database luôn, ví dụ muốn tạo mới 1 nhân viên thì dùng sqlcommand tạo trực tiếp trên database luôn.

Em thấy làm cách đó khá nhanh, không phải nạp vào class rồi khi đóng lại dùng sqlcommand update lại dữ liệu, nhưng nếu làm vậy thì mục đích của OOP C# là gì khi không cần dùng tới?

Cám ơn anh chị.

Mình ko code C# nên mình ko hình dung được cách code bên đó, nhưng qua bạn describe thì mình thử cho ex thử xem đúng ý bạn ko nhé?
Đầu tiên là cách via object:
1/ function updateEmployeeInfor(Employee: employ) // rồi vô trong lấy các propeties của object employ gán vô SQL commands.
2/ Là call SQL commands directly:

function updateEmployeeInfor(employName: String, employAge: Int, employEmail: String, employAdress: String, employSalary: Float, etc...) 

Nếu đúng vậy thì mình thử analyze nhé:
1/ Sure là cách 1 gọn hơn thấy rõ, viết dễ dàng, concise. Nếu function gọi 1 lần ko sao, chớ dùng nhiều nơi mà viết cách thứ 2 ko ổn chút nào dễ sai xót lắm.
2/ Unit test: cái này gần như tương tự ý số 1, quá phiền phức để viết unit test, vì đa số khi viết unit test thì ta sẽ có 1 file json chứa dummy data, chỉ việc parse json vào object Employee, rồi đem đi call cái function là done, đằng này bạn viết cách 2 thì bạn phải tự thêm dummy data ở mỗi function testing.

4 Likes

Em cũng chưa học tới json nên em cũng không biết rõ, tại nếu làm cách 1 thì khi mở form lần đầu phải nạp hết dữ liệu từ database vào Arraylist NhanVien, xong khi đóng form thì nó lại lấy Arraylist NhanVien đó nạp lại vào database. Ở cách 2 thì mình chỉ cần dùng câu lệnh sqlcommand để làm việc trực tiếp trên database xong mình cập nhật lại form là nó update luôn cho mình.

Trong ứng dụng thực tế không chỉ có mỗi form của e thao tác với SQL đó, mà còn nhiều người khác nữa. Việc thao tác trực tiếp trên sql cũng là để đồng bộ dữ liệu và tránh tối đa conflict. Cho nên người ta sẽ không làm cách 1.

Còn về OOP ở đây có lẽ e đang hiểu sai, SQLCommand cũng là một object, DataTable cũng là 1 object, DataRow cũng là 1 object chứ không nhất thiết phải parse ra dạng class Nhanvien.

Nếu e thực sự muốn parse ra kiểu dữ liệu NhanVien, để xử lý cho tối ưu thì có thể áp dụng EntityFramework, (Khuyên dùng)

4 Likes

Vậy là mình phải làm cách 2 phải không anh? Có cái Framework nào giống như cái anh nói mà dùng cho ngôn ngữ java không vậy?

Nghĩ mới thấy anh nói đúng, nếu 2 người cùng lúc dùng chung 1 phần mềm thì sửa thông tin theo cách 1 nó không đồng bộ được.
Cám ơn anh đã đả thông kinh mạch em.

Java thì a không biết, hỏi thử trên dnh xem có ai biết không.

2 Likes

Có thể giải thích cho mình sao dùng cách 1 ko đồng bộ ko?

2 Likes

Vẫn đồng bộ được nếu bạn đặt thời gian để sau N giây hay mili giây thì lại kiểm tra dữ liệu trong hệ quản trị CSDL một lần để nạp lên lại nếu có sự thay đổi dữ liệu (do người khác thay đổi hoặc do chính bạn nhưng không phải ngay trên form đang làm việc). Cách đó có phải lại rách việc ra không? Còn nếu không làm vậy thì việc đọc lên nó nằm vào biến, tức RAM thì nếu không có thao tác lưu dữ liệu, nó không đồng bộ.

3 Likes

Thiệt do mình già ngu hay sao mà bạn nói vẫn ko hiểu nhé.
Thế cách số 2 thì data ko lưu trên RAM à? vậy trong lúc SQL excute thì data của toàn bộ quá trình đó đang nằm ở đâu?
Còn việc synchronize thì liên quan gì đến cách excute SQL gián tiếp hay trực tiếp?
Đơn giản là bạn làm cách nào đi nữa thì việc bạn làm chỉ đang là 1 phía từ client đẩy data lên server và serve chỉ trả về signal cho biết là success or not? chớ làm cách nào mà server nó tự báo cho client là data đã bị client khác change? đây lại alf câu chuyện khác, cái này đâu phải socket đâu, mà có là socket nhưng chưa qua bước register observer cũng vậy thôi ko có gì theo dõi quá trình amend data cả.

4 Likes

Bạn hiểu đúng chứ không sai, thậm chí sâu sắc nữa.

Nhưng ở đây là chủ topic đang không phân biệt ra thao tác đọc và ghi. Nếu có đọc và ghi thì 1 và 2 ở trên xem ra cũng không khác nhau nhiều, mà thậm chí phải cả 2 kết hợp mới được. Không có gì hết thì phải nhập bằng tay và lưu chứ lấy đâu mà nạp từ CSDL lên. Nói cách khác, việc tạo mới một Employee sẽ khác với việc sửa/ cập nhật một Employee.

Chủ topic nên xem lại vấn đề xem thay đổi dữ liệu trực tiếp với không trực tiếp ý là sao, nghe rối quá rối hoặc chủ topic đang nhầm lẫn sao đó. Thay đổi trực tiếp chắc chỉ dành để thử câu lệnh trên cửa sổ lệnh do DBMS trang bị :smiley: Mà đã gọi là phần mềm chắc không có nhiều lập trình viên mong muốn người dùng sử dụng phần mềm ứng dụng theo kiểu gõ trực tiếp vào cửa sổ lệnh DBMS trang bị trừ đó là chính DBMS.

“đồng bộ” ở đây cũng có nhiều cách hiểu khác nhau. Có lẽ chúng ta không hiểu nhau chỗ này khi với chủ đề này mình chỉ giới hạn việc đồng bộ ở chỗ là lưu xuống cơ sở dữ liệu và nếu có ai khác đang thao tác trên chính biểu ghi đó thì… phải làm sao dàn xếp việc này giữa các client. Có lẽ vì thế mà Google Docs khi nhiều người đánh chung một văn bản nó phải cho người ta biết, không thì thành mớ hỗn mang.

Còn mấy cái đồng bộ kiểu khác thì mình không bàn ở đây vì nó quá phong phú. Và ngày nay còn có kiểu client - client bỏ qua server luôn, cái nào cần đến trung gian server mới dùng đến thì nó không còn là mô hình server - client truyền thống nữa hoặc các server đồng bộ cho nhau không có vai trò client… Không đủ kiến thức để bàn về đồng bộ nói chung.

7 Likes

Vấn đề của bạn ấy không phải là execute SQL trực tiếp hay gián tiếp mà ở chỗ lưu data lúc nào, ngay khi chỉnh sửa hay khi đóng form.
Có thể vì sinh viên suy nghĩ sẽ hơi khác nên đặt vấn đề khó hiểu:

  • cách 1: Mở form, load data, (parse thành object ), sửa object, đóng form, (parse object thành data), lưu data xuống SQL
  • cách 2, Mở form, load data, sửa và lưu data xuống SQL, đóng form

Với cách 1 thì data sau khi sửa không cập nhật ngay. Do đó nếu 2 người mở form cùng một lúc, data không thay đổi trong quá trình chỉnh sửa nên có refresh cũng không cập nhật data mới. Hơn nữa khi đang làm việc mà cúp điện coi như mất toi công sức.
Với cách 2 data ngay lập tức đẩy lên CSDL, và có thể dùng nhiều cách như timer, hay F5 để refresh data bất kỳ lúc nào.

Đồng bộ chỉ hiểu một cách tương đối, chứ không phải máy móc như các bác sr.

5 Likes

Tớ có đọc các câu trả lời và các phân tích của mọi người. Tớ nghĩ tớ chỉ muốn thêm/làm rõ 1 số điểm thôi.

  1. Với bài tập lớn của Cuong, tớ hiểu bạn ấy làm với 1 application + 1 DB, cả 2 được deploy ở chung 1 máy (local). Với setup đó, tớ nghĩ không khó hiểu nếu mình implement dùng sqlcommand để thao tác trực tiếp với local DB luôn.
    Với use case đó, OOP chỉ dùng khi mô hình hóa các form giao diện, không cần để mô hình hóa dữ liệu nữa.
  2. Trong TH có thêm 1 process nữa sử dụng được application, cả 2 cách đều sẽ không giải quyết được vấn đề toàn vẹn dữ liệu khi cùng update trên 1 record.
    Solution cho vấn đề đó là transaction. DB system sẽ xử lý việc đồng bộ internally, và đảm bảo sự toàn vẹn dữ liệu (tớ chắc chắn cậu không muốn khi đang insert dở 5 nhân viên vào 1 bảng, rồi cập nhật fail bảng gán quyền, cậu sẽ có 5 nhân viên ất ơ không có quyền gì cả).
    Khi dùng transaction, cậu có thể chọn mô hình hóa dữ liệu của cậu và sử dụng ORM để làm việc với CSDL, hoặc cậu manually tạo ra transaction và các câu query, rồi commit.
  3. Ở Java, cậu có thể dùng Hibernate hoặc JPA cho ORM.

Hi vọng nó giúp cậu!

4 Likes

Ý em là đúng như của anh nói. Tại không biết diễn đạt sao cho nó đúng nên hơi dài dòng, hoặc hơi lạc sang những cái khác.

Cám ơn các anh chị đã giải thích câu hỏi của em, vì em cũng mới học nên không hiểu sâu và kĩ nên đặt câu hỏi gây khó hiểu cho anh chị.

Còn về đồng bộ thì em chỉ nghĩ đơn giản là nếu ứng dụng đó có 2 máy dùng và 1 máy (máy A) thực hiện chỉnh sửa (update, create, delete…) thì máy 2 (máy B) chỉ cần refresh lại form (bằng button tạo sẵn để refresh hoặc cho thời gian refresh tự động).

  • Với cách 1: Thì khi người dùng máy A kết thúc phiên làm việc với form (đóng form) thì dữ liệu mới được cập nhật lên database, khi đó nếu như máy B sử dụng trong quá trình máy A chưa đóng form thì dữ liệu sẽ không đồng bộ được.
  • Với cách 2: Vì những thay đổi (update, create, delete…) sẽ thực hiện trên database (bằng sqlcommand) khi máy A chỉnh sửa nên máy B chỉ cần refresh (hoặc form tự động refresh) thì máy B sẽ thấy được dữ liệu mà máy A thay đổi.

Ở đây em sẽ bỏ qua trường hợp nếu máy A và B cùng lúc thao tác trên cùng 1 đối tượng.

Do trình độ chuyên môn em chưa có nên anh chị thông cảm.

Sao bạn thiên vị cách của bạn thế? và cách bạn giải thích nó ko hợp lý vì thực tế ai làm vậy bao giờ?
Sao cách 2 thì mở form load data, amend rồi save ngay, xong mới close form.
Cách 1 lại load data, parse object, amend object, close form mới save? sao ko save ngay lúc amend object như cách 2? đừng nói phải execute transaction nhiều lần tốn resource nha? effort y chan cách 2 của bạn ko khác chút nào.
Nên giải thích theo cách làm thực tế đừng giải thích theo kiểu cho sinh viên có đầy lỗ hổng rất hại họ.

6 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?