Phân tích yêu cầu thiết kế một website tin tức

Bài này mình muốn đưa ra việc phân tích yêu cầu xây dựng một website tin tức bao gồm các chức năng dưới đây

Các chức năng trong phần quản trị của website. (Tùy từng user được phân quyền mà có các chức năng cụ thể khác nhau)
Quản lý các chuyên mục
- Quản lý chuyên mục đa cấp
- Có thể thêm mới, sửa xóa các chuyên mục
- Sắp đặt chuyên mục: Có thể quản lý hiển thị của các chuyên mục trên trang chủ. Thường được chia làm các phần head menu, left menu, right menu. Khi quản trị cho phép những chuyên mục nào hiển thị trên menu tương ứng
 
Quản lý người dùng
- Quản lý người dùng, phân quyền cho các UserName
- Có thể thêm mới, sửa xóa các UserName

Quản lý các banner
- Có thể thêm mới, cập nhật, xóa các banner
- Có thể cài đặt các quảng cáo hiển thị ở các bị trí trên trang chủ của website

Quản lý và thiết đặt câu hỏi cho phần Vote (Bình chọn)

- Tạo câu hỏi mới, Offline câu hỏi đang dùng
- Thêm, sửa các câu trả lời của câu hỏi

Quản lý các thành viên.
- Thêm mới thành viên
- Khóa user của thành viên nến thấy có vi phạm
- Thay đổi các thông tin của thành viên

Thiết lập các thông số của website như Title, Mailserver, MaiContact… (Các thông số này sẽ được lưu ở file xml)

Quản lý bài viết

- Nếu có quyền viết bài: : Nếu UserName này chỉ có quyền viết bài thì chỉ có thể viết bài và các bài viết của người này là ở trạng thái chờ duyệt. Có thể sửa, xóa bài viết khi chưa được duyệt hoặc đăng
- Duyệt bài: Có thể thêm, sửa, xóa hoặc duyệt bài chờ đăng.
- Đăng bài: Có thể thêm, sửa, xóa các bài viết, đăng các bài đang chờ duyệt hoặc chờ đăng
* Các bài viết có trạng thái đã đang thì mới được hiển thị trên website

Phần giao diện
- Có chức năng thống kê website. Thống kế số người đang xem, số lượt truy cập
- Có chức năng tìm kiếm bài viết
- Có chức năng Vote (Bình chọn)
- Hiển thị các chuyên mục được chọn dạng menu
- Tạo chức năng đăng ký và quản lý thành viên
- - Cho phép người dùng đăng ký thành viên và gửi ý kiến phản hồi về bài viết sau khi đã đăng nhập

Thiết kế cơ sở dữ liệu
Các bảng chính

Ngoài ra còn các bảng phụ như bảng

Thống kê website TB_ Statistics

Các website liên kết: TB_Website

Phần bình chọn:
TB_ Poll
TB_ PollChoices
TB_ PollIPs

Video hướng dẫn tạo cơ sở dữ liệu

 [vimeo:15615811]

Tạo các kiểu dữ liệu do người dùng định nghĩa trong mssql

Trong SQL server đã định nghĩa sẵn cho bạn các kiểu dữ liệu. Nhưng SQL cũng có chế độ mở để cho phép người dùng tự định nghĩa kiểu dữ liệu riêng của bạn.
SQL server, kiểu dữ liệu, người dùng, định nghĩa,

Khi bạn đã tạo một kiểu dữ liệu do bạn tự định nghĩa bạn có thể sử dụng nó trong cơ sở dữ liệu của bạn như các liểu dữ liệu mà SQL System đã định nghĩa.

Để tạo kiểu dữ liệu tự định nghĩa bạn phải sử dụng các kiều dữ liệu do hệ thống cung cấp. Ví dụ bạn có thể tạo một loại dữ liệu là KhoaChinh và định nghĩa nó như varchar hoặc Int nhưng không thể định nghĩa nó như một loại dữ liệu không tồn tại. Một điều nữa là bạn cần phải định nghĩa kiểu dữ liệu của bạn trước khi bạn sử dụng nó.

Để định nghĩa bằng lệnh SQL bạn sử dụng sp_addType

Lấy minh họa là bạn muốn tạo kiểu dữ liệu là KhoaChinh để khi sử dụng trường nào đó là Prymary Key sẽ luôn là varchar và Length là 50 như ví dụ sau:

Exec sp_addtype 'KhoaChinh', 'varchar(50)', 'Not null'

Khi chạy xong lệnh này giờ bạn đã chính thức có kiểu dữ liệu là KhoaChinh và bạn sử dụng nó như các kiểu dữ liệu khác như ví dụ sau:
Create Table TB_DBType
(
    TestCode KhoaChinh Primary Key,
    TestName nvarchar(100),
    OrderID int
)
Bạn thấy trong lệnh tạo Bảng TB_DBType ở trên tôi có tạo trường TestCode là khóa chính và kiểu dữ liệu là KhoaChinh do tôi đã định nghĩa là varchar(50) mà không phải một kiểu dữ liệu hệ thống của SQL server . Đó là ví dụ đơn giản để bạn biết về kiểu dữ liệu do người dùng định nghĩa. Qua đó bạn có thể tự định nghĩa cho mình các kiểu dữ liệu mà bạn mong muốn

Để xóa các kiểu dữ liệu do người dùng định nghĩa bạn sùng lệnh sp_dropType nhưng bạn cần chú ý là kiểu dữ liệu đang muốn xóa này chưa được sử dụng trong cơ sở dữ liệu của bạn
Ví dụ để xóa Kiểu dữ liệu KhoaChinh ở trên bạn dùng lệnh:
exec sp_droptype 'KhoaChinh'
Về lý thuyết thì bạn có thể định nghĩa kiểu dữ liệu riêng của bạn để sử dụng cho tất cả các Database có trong hệ quản trị CSDL của bạn bằng việc tạo nó trong cơ sở dữ liệu model của hệ thống, nhưng tôi khuyến cáo bạn nếu có định nghĩa thì nên định nghĩa trong nội cơ sở dữ liệu bạn đang thao tác thôi nếu không khi triển khai bạn sẽ gặp phải những lỗi không mong muốn. đó là bạn lại phải định nghĩa kiểu dữ liệu đó trên Database server nơi bạn triển khai, Nếu bạn lại không có quyền quản trị cao nhất thì lúc đó không triển khai ứng dụng của bạn được

Bài viết này có tính chất tham khảo, Bạn có hứng thú có thể tự định nghĩa cho bạn kiểu dữ liệu riêng nhé

Clustered Index In SQL server

Clustered index là loại index theo đó các bản ghi trong bảng được sắp thứ tự theo trường index. Khi bảng được tạo clustered index thì bản thân nó trở thành một cây index, với các node lá chứa khóa là các trường được index và cũng đồng thời chứa tất cả các trường còn lại của bảng.

Vì các bản ghi chỉ có thể được sắp xếp trên cây index theo một thứ tự nhất định nên mỗi bảng chỉ có thể có tối đa một clustered index. Bạn tạo clustered index như sau:

CREATE CLUSTERED INDEX index_name ON dbo.Tblname(Colname1, Colname2...)

Khi bảng đã có clustered index thì các index khác (nonclustered) sẽ dùng khóa của trường clustered index làm con trỏ để trỏ về bản ghi tương ứng (nếu bảng không có clustered index thì một giá trị RID nội bộ được dùng).

Clustered index không đòi hỏi phải duy nhất (unique). Nhưng khi nó không duy nhất thì khóa index được gắn thêm một giá trị 4-byte ngẫu nhiên để đảm bảo các node index vẫn là duy nhất. Mục đích của việc này là để cho con trỏ trong các index khác luôn trỏ đến đến duy nhất một bản ghi, khi đó con trỏ sẽ bao gồm khóa index + chuỗi 4 byte được gắn thêm.

Việc gắn thêm như vậy làm tăng kích thước của clustered index cũng như các index khác, nên trong đa số tình huống thực tiễn bạn nên tạo clustered index là duy nhất. Thực tế, theo mặc định một clustered index duy nhất sẽ được tạo khi khai báo khóa chính.

Việc tìm kiếm theo trường có clustered index tối ưu hơn so với non-clustered index vì nó bỏ qua được bước bookmark lookup (do tất cả các trường dữ liệu đã có sẵn tại node index). Ta hãy so sánh hiệu năng của hai loại index thông qua một ví dụ: bảng Customer vốn đã có clustered index trên trường CustomerID; giờ ta hãy copy dữ liệu sang một bảng mới và tạo non-clustered index cho CustomerID; sau đó thực hiện cùng một câu lệnh trên hai bảng.

USE AdventureWorks
GO
SELECT *
INTO Sales.Customer_NC
FROM Sales.Customer
GO
CREATE INDEX Idx_CustomerID_NC ON Sales.Customer_NC(CustomerID)
GO
-- #1
SELECT CustomerID,CustomerType
FROM Sales.Customer WHERE CustomerID = 27684

-- #2
SELECT CustomerID,CustomerType
FROM Sales.Customer_NC WHERE CustomerID = 27684

 

Như phương án thực thi cho thấy, câu lệnh thứ nhất (có clustered index) chỉ có chi phí bằng một nửa so với câu lệnh thứ hai (nonclustered index), do câu lệnh thứ hai cần thêm thao tác bookmark lookup (RID lookup ở trong hình). Bạn có thể hình dung clustered index là một covering index với độ bao phủ là toàn bộ các cột trong bảng, nhưng không chiếm thêm không gian lưu trữ riêng cho index.

Cũng vì dữ liệu được lưu cùng với node index nên các lệnh tìm kiếm theo khoảng luôn được trợ giúp bởi clustered index. Trở lại hai bảng trong ví dụ trên:

SELECT CustomerID,CustomerType
FROM Sales.Customer WHERE CustomerID BETWEEN 20000 and 30000

SELECT CustomerID,CustomerType
FROM Sales.Customer_NC WHERE CustomerID BETWEEN 20000 and 30000

 

Hãy tạm bỏ qua dòng khuyến cáo (“Missing index…”) của SQL Server. Ta thấy là câu lệnh thứ nhất được thực hiện bằng index seek, trong khi câu lệnh thứ hai dẫn đến quét bảng (table scan) mặc dù trường cần tìm đã có index. Lý do là vì câu lệnh tìm kiếm theo khoảng như trên thường trả về nhiều bản ghi, nếu dùng index sẽ tạo ra nhiều thao tác bookmark lookup (mỗi bản ghi tìm được là một lần lookup), dẫn đến chi phí tăng cao. Trong trường hợp này nó còn vượt quá chi phí quét bảng. Vì thế bộ tối ưu hóa (Optimizer) khi đánh giá các phương án đã chọn cách quét bảng. Với clustered index thì thao tác nhảy thẳng đến từng node (index seek) luôn đủ để lấy được kết quả; vì index seek đã là tối ưu nên không có phương án nào khác cần xem xét.


Phiên bản áp dụng: Tất cả các phiên bản

Thủ tục tạo chuỗi ký tự ngẫu nhiên trong Mssql

Bạn muốn tạo một chuỗi ký từ ngẫu nhiên như việc tạo Password, Hay tạo mã sản phẩm? Trên hmweb đã có bài tạo chuỗi ngẫu nhiên bằng C#. Bài này tôi giới thiệu thủ tục trong SQL server

Thủ tục được tạo như sau:

CREATE PROCEDURE [dbo].[sp_GeneratePassword]
    @Length int
AS
BEGIN
    DECLARE @RandomID varchar(32)
    DECLARE @counter smallint
    DECLARE @RandomNumber float
    DECLARE @RandomNumberInt tinyint
    DECLARE @CurrentCharacter varchar(1)
    DECLARE @ValidCharacters varchar(255)
    SET @ValidCharacters='ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
    DECLARE @ValidCharactersLength int
    SET @ValidCharactersLength = len(@ValidCharacters)
    SET @CurrentCharacter = ''
    SET @RandomNumber = 0
    SET @RandomNumberInt = 0
    SET @RandomID = ''
    SET NOCOUNT ON
    SET @counter = 1
    WHILE @counter < (@Length + 1)
    BEGIN
        SET @RandomNumber = Rand()
        SET @RandomNumberInt = Convert(tinyint, 
            ((@ValidCharactersLength - 1) * @RandomNumber + 1))
        SELECT @CurrentCharacter = 
            SUBSTRING(@ValidCharacters, @RandomNumberInt, 1)
        SET @counter = @counter + 1
        SET @RandomID = @RandomID + @CurrentCharacter
    End
    Select @RandomID As Pass
END

Thủ tục này sẽ lấy chuỗi ngâu nhiên bao gồm @Length ký tự từ chuỗi cho trước ABC...YZ1234567890.
Ví dụ bạn muốn lấy chuỗi ngẫu nhiên có độ dài là 8 ký tự bạn thực hiện: Exec sp_GeneratePassword 8 Sẽ sinh ra cho bạn chuỗi '9WAVZ3'

Thủ tục trên chỉ lấy ngẫu nhiên trong dãy ký tự đã có trước. Giờ bạn cải tiến đi một chút để dãy ký tự này cũng được chuyền vào thành tham số như sau:

CREATE  PROCEDURE sGeneratePassword_InputString 
    @Length int,
    @InputString nvarchar(255)
AS
BEGIN
    DECLARE @RandomID varchar(32)
    DECLARE @counter smallint
    DECLARE @RandomNumber float
    DECLARE @RandomNumberInt tinyint
    DECLARE @CurrentCharacter varchar(1)
    DECLARE @InputStringLength int
    SET @InputStringLength = len(@InputString)
    SET @CurrentCharacter = ''
    SET @RandomNumber = 0
    SET @RandomNumberInt = 0
    SET @RandomID = ''
    SET NOCOUNT ON
    SET @counter = 1
    WHILE @counter < (@Length + 1)
    BEGIN
            SET @RandomNumber = Rand()
            SET @RandomNumberInt = Convert(tinyint, ((@InputStringLength - 1) * @RandomNumber + 1))
            SELECT @CurrentCharacter = SUBSTRING(@InputString, @RandomNumberInt, 1)
            SET @counter = @counter + 1
            SET @RandomID = @RandomID + @CurrentCharacter
    End
    Select @RandomID As Pass
END

Giờ bạn chạy thử với lệnh:

 

Exec sGeneratePassword_InputString 8,'abcqwertyuiolkjAHSNKA09876jh&654321'


Biến thứ 2 là tùy ý bạn truyền vào một dãy ký tự tùy thích kết quả minh họa là '60rje52u', Với mỗi lần thực thi thì kết quả sẽ một khác

Hy vọng nó có ích với bạn. Chúc bạn thành công

 

 

Sao lưu tất cả database của SQL Server

Đôi khi nhiều thứ dường như có vẻ phức tạp thì lại đơn giản hơn những gì bạn nghĩ và đây là sức mạnh của việc sử dụng câu lệnh T-SQL để thực hiện những công việc lặp đi lặp lại. Một trong những công việc này có lẽ là việc backup tất cả các cơ sở dữ liệu...

Đôi khi nhiều thứ dường như có vẻ phức tạp thì lại đơn giản hơn những gì bạn nghĩ và đây là sức mạnh của việc sử dụng câu lệnh T-SQL để thực hiện những công việc lặp đi lặp lại. Một trong những công việc này có lẽ là việc backup tất cả các cơ sở dữ liệu trong server của bạn. Điều này không có gì lớn nếu như bạn chỉ có một vài cơ sở dữ liệu, nhưng có những server chứa tới hàng trăm cơ sở dữ liệu trên một instance của SQL Server thì vấn đề bắt đầu nảy sinh. Bạn có thể sử dụng tiện ích Enterprise Manager để backup các cơ sở dữ liệu, hoặc thậm chí dùng Maintenance Plans để lên kế hoạch bảo trì, songT-SQL vẫn cho phép bạn thực hiện dễ dàng và nhanh chóng hơn nhiều.

Với việc sử dụng của T-SQL bạn có thể tạo ra các lệnh dự phòng của bạn và với việc sử dụng con trỏ, bạn có thể trỏ qua tất cả các cơ sở dữ liệu của bạn để backup chúng từng cái một. Đây là một quá trình thẳng tiến và bạn chỉ cần một số ít các lệnh để làm điều này.

Đây là script cho phép bạn sao lưu mỗi cơ sở dữ liệu trong instance SQL Server của bạn. Bạn cần thay đổi biến @path để dẫn tới thư mục dự phòng phù hợp và các tập tin sao lưu sẽ đưa vào tên có dạng "DBnameYYYDDMM.BAK".

DECLARE @name VARCHAR(50) -- database name  
DECLARE @path VARCHAR(256) -- path for backup files  
DECLARE @fileName VARCHAR(256) -- filename for backup  
DECLARE @fileDate VARCHAR(20) -- used for file name 
SET @path = 'C:\Backup\'  
SELECT @fileDate = CONVERT(VARCHAR(20),GETDATE(),112) 
DECLARE db_cursor CURSOR FOR  
SELECT name 
FROM master.dbo.sysdatabases 
WHERE name NOT IN ('master','model','msdb','tempdb')  
OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO @name   
WHILE @@FETCH_STATUS = 0   
BEGIN   
       SET @fileName = @path + @name + '_' + @fileDate + '.BAK'  
       BACKUP DATABASE @name TO DISK = @fileName  
       FETCH NEXT FROM db_cursor INTO @name   
END   
CLOSE db_cursor   
DEALLOCATE db_cursor
Trong script này chúng ta bỏ qua các cơ sở dữ liệu hệ thống, nhưng những cơ sở dữ liệu này cũng có thể đưa vào dễ dàng như vậy. Bạn cũng có thể thay đổi scropt này thành một thủ tục được lưu trữ và truyền vào tên cơ sở dữ liệu hoặc nếu để là NULL thì nó sẽ sao lưu tất cả các cơ sở dữ liệu.