狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

面試官問單表數(shù)據(jù)量大一定要分庫分表嗎?我們用六個字和十張圖回答

admin
2023年5月19日 11:30 本文熱度 1429

1 文章概述

在業(yè)務(wù)發(fā)展初期單表完全可以滿足業(yè)務(wù)需求,在阿里巴巴開發(fā)手冊也建議:單表行數(shù)超過500萬行或者單表容量超過2GB才推薦進行分庫分表,如果預(yù)計三年后數(shù)據(jù)量根本達不到這個級別,請不要在創(chuàng)建表時就分庫分表。

但是隨著業(yè)務(wù)的發(fā)展和深入,單表數(shù)據(jù)量不斷增加,逐漸成為業(yè)務(wù)系統(tǒng)的瓶頸。這是為什么呢?

從宏觀層面分析任何物體都必然有其物理極限。1965年英特爾創(chuàng)始人摩爾預(yù)測:集成電路上可容納的元器件的數(shù)目,約每隔24個月增加一倍,性能提升一倍,即計算機性能每兩年翻一番。

但是摩爾定律會有終點嗎?有些科學(xué)家認為摩爾定律是有終點的:半導(dǎo)體芯片單位面積可集成的元件數(shù)量是有極限的,因為半導(dǎo)體芯片制程工藝的物理極限為2到3納米。當然也有科學(xué)家不支持這種說法,但是我們可以從中看出物理極限是很難突破的,當單表數(shù)據(jù)量達到一定規(guī)模時必然也達到極限。

從細節(jié)層面分析我們將數(shù)據(jù)保存在數(shù)據(jù)庫,實際上是保存在磁盤中,一次磁盤IO操作需要經(jīng)歷尋道、旋轉(zhuǎn)延時、數(shù)據(jù)傳輸三個步驟,那么一次磁盤IO耗時公式如下:

單次IO時間 = 尋道時間 + 旋轉(zhuǎn)延遲 + 傳送時間

總體來說上述操作都較為耗時,速度和內(nèi)存相比有著數(shù)量級的差距,當數(shù)據(jù)量過大磁盤這一瓶頸更加明顯。那么應(yīng)該怎么辦?處理單表數(shù)據(jù)量過大有以下六字口訣:刪、換、分、拆、異、熱。


刪是指刪除歷史數(shù)據(jù)并進行歸檔。換是指不要只使用數(shù)據(jù)庫資源,有些數(shù)據(jù)可以存儲至其它替代資源。分是指讀寫分離,增加多個讀實例應(yīng)對讀多寫少的互聯(lián)網(wǎng)場景。拆是指分庫分表,將數(shù)據(jù)分散至不同的庫表中減輕壓力。異指數(shù)據(jù)異構(gòu),將一份數(shù)據(jù)根據(jù)不同業(yè)務(wù)需求保存多份。熱是指熱點數(shù)據(jù),這是一個非常值得注意的問題。


2 刪

我們分析這樣一個場景:消費者會經(jīng)常查詢一年之前的訂單記錄嗎?答案是一般不會,或者說這種查詢需求量很小。

根據(jù)上述分析那么一年前的數(shù)據(jù)我們就沒有必要放在單表這張業(yè)務(wù)主表,可以將一年前的數(shù)據(jù)遷移到歷史歸檔表。

在查詢歷史數(shù)據(jù)表時,可以限制查詢條件如必須選擇日期范圍,日期范圍不能超過X個月等等從而減輕查詢壓力。

處理歷史存量數(shù)據(jù)比較簡單,因為存量數(shù)據(jù)一般是靜態(tài)的,此時狀態(tài)已經(jīng)不再改變了。數(shù)據(jù)處理一般分為以下兩個步驟:

(1) 遷移一年前數(shù)據(jù)至歷史歸檔表
(2) 根據(jù)主鍵分批刪除主表數(shù)據(jù)

不能一次性刪除所有數(shù)據(jù),因為數(shù)據(jù)量太大可能會引發(fā)超時,而是應(yīng)該根據(jù)ID分批刪除,例如每次刪除500條數(shù)據(jù)。

第一步查詢一年前主鍵最大值和最小值,這是我們需要刪除的數(shù)據(jù)范圍:

select
MIN(idAS minId, 
MAX(idAS maxId 
from biz_table 
where create_time < DATE_SUB(now(),INTERVAL 1 YEAR)

第二步刪除數(shù)據(jù)時不能一次性全部刪掉,因為很可能會超時,我們可以通過代碼動態(tài)更新endId進行批量刪除:

delete from biz_table 
where id >= #{minId}
AND id <= #{maxId}
AND id <= #{endId}
LIMIT 500


3 換

換是指換一個存儲介質(zhì),當然并不是說完全替換,而是用其它存儲介質(zhì)對數(shù)據(jù)庫做一個補充。例如海量流水記錄,這類數(shù)據(jù)量級是巨量的,根本不適合存儲在MySQL數(shù)據(jù)庫中,那么這些數(shù)據(jù)可以存在哪里呢?

現(xiàn)在互聯(lián)網(wǎng)公司一般都具備與之規(guī)模相對應(yīng)的大數(shù)據(jù)服務(wù)或者平臺,那么作為業(yè)務(wù)開發(fā)者要善于應(yīng)用公司大數(shù)據(jù)能力,減輕業(yè)務(wù)數(shù)據(jù)庫壓力。


3.1 消息隊列

這些海量數(shù)據(jù)可以存儲至Kafka,因為其本質(zhì)上就是分布式的流數(shù)據(jù)存儲系統(tǒng)。使用Kafka有如下優(yōu)點:

第一個優(yōu)點是Kafka社區(qū)活躍功能強大,已經(jīng)成為了一種事實上的工業(yè)標準。大數(shù)據(jù)很多組件都提供了Kafka接入組件,經(jīng)過生產(chǎn)驗證并且對接成本較小,可以為下游業(yè)務(wù)提供更多選擇。

第二個優(yōu)點是Kafka具有消息隊列本身的優(yōu)點例如解耦、異步和削峰。



假設(shè)這些海量數(shù)據(jù)都已經(jīng)存儲在Kafka,現(xiàn)在我們希望這些數(shù)據(jù)可以產(chǎn)生業(yè)務(wù)價值,這涉及到兩種數(shù)據(jù)分析任務(wù):離線任務(wù)和實時任務(wù)。

離線任務(wù)對實時性要求不高,例如每天、每周、每月的數(shù)據(jù)報表統(tǒng)計分析,我們可以使用基于MapReduce數(shù)據(jù)倉庫工具Hive進行報表統(tǒng)計。

實時任務(wù)對實時性要求高,例如根據(jù)用戶相關(guān)行為推薦用戶感興趣的商品,提高用戶購買體驗和效率,可以使用Flink進行流處理分析。例如運營后臺查詢分析,可以將數(shù)據(jù)同步至ES進行檢索。

還有一種分類方式是將任務(wù)分為批處理任務(wù)和流處理任務(wù),我們可以這么理解:離線任務(wù)一般使用批處理技術(shù),實時任務(wù)一般使用流處理技術(shù)。


3.2 API

上一個章節(jié)我們使用了Kafka進行海量數(shù)據(jù)存儲,由于其強大兼容性和集成度,可以作為數(shù)據(jù)中介將數(shù)據(jù)進行中轉(zhuǎn)和解耦。

當然我們并不是必須使用Kafka進行中轉(zhuǎn),例如我們直接可以使用相關(guān)Java API將數(shù)據(jù)存入Hive、ES、HBASE等。

但是我并不推薦這種做法,因為將保存流水這樣操作耦合進業(yè)務(wù)代碼并不合適,違反了高內(nèi)聚低耦合的原則,盡量不要使用。


3.3 緩存

從廣義上理解換這個字,我們還可以引入Redis遠程緩存,把Redis放在MySQL前面,攔下一些高頻讀請求,但是要注意緩存穿透和擊穿問題。

緩存穿透和擊穿從最終結(jié)果上來說都是流量繞過緩存打到了數(shù)據(jù)庫,可能會導(dǎo)致數(shù)據(jù)庫掛掉或者系統(tǒng)雪崩,但是仔細區(qū)分還是有一些不同,我們分析一張業(yè)務(wù)讀取緩存流程圖。



我們用文字簡要描述這張圖:

(1) 業(yè)務(wù)查詢數(shù)據(jù)時首先查詢緩存,如果緩存存在數(shù)據(jù)則返回,流程結(jié)束

(2) 如果緩存不存在數(shù)據(jù)則查詢數(shù)據(jù)庫,如果數(shù)據(jù)庫不存在數(shù)據(jù)則返回空數(shù)據(jù),流程結(jié)束

(3) 如果數(shù)據(jù)庫存在數(shù)據(jù)則將數(shù)據(jù)寫入緩存并返回數(shù)據(jù)給業(yè)務(wù),流程結(jié)束

假設(shè)業(yè)務(wù)方要查詢A數(shù)據(jù),緩存穿透是指數(shù)據(jù)庫根本不存在A數(shù)據(jù),所以根本沒有數(shù)據(jù)可以寫入緩存,導(dǎo)致緩存層失去意義,大量請求會頻繁訪問數(shù)據(jù)庫。

緩存擊穿是指請求在查詢數(shù)據(jù)庫前,首先查緩存看看是否存在,這是沒有問題的。但是并發(fā)量太大,導(dǎo)致第一個請求還沒有來得及將數(shù)據(jù)寫入緩存,后續(xù)大量請求已經(jīng)開始訪問緩存,這是數(shù)據(jù)在緩存中還是不存在的,所以瞬時大量請求會打到數(shù)據(jù)庫。

我們可以使用分布式鎖加上自旋解決這個問題,本文給出一段示例代碼,具體原理請參看我之前的一篇文章:緩存穿透與擊穿問題解決方案

/**
 * 業(yè)務(wù)回調(diào)
 *
 * @author 微信公眾號「JAVA前線」
 *
 */

public interface RedisBizCall {

    /**
     * 業(yè)務(wù)回調(diào)方法
     *
     * @return 序列化后數(shù)據(jù)值
     */

    String call();
}

/**
 * 安全緩存管理器
 *
 * @author 微信公眾號「JAVA前線」
 *
 */

@Service
public class SafeRedisManager {
    @Resource
    private RedisClient RedisClient;
    @Resource
    private RedisLockManager redisLockManager;

    public String getDataSafe(String key, int lockExpireSeconds, int dataExpireSeconds, RedisBizCall bizCall, boolean alwaysRetry) {
        boolean getLockSuccess = false;
        try {
            while(true) {
                String value = redisClient.get(key);
                if (StringUtils.isNotEmpty(value)) {
                    return value;
                }
                /** 競爭分布式鎖 **/
                if (getLockSuccess = redisLockManager.tryLock(key, lockExpireSeconds)) {
                    value = redisClient.get(key);
                    if (StringUtils.isNotEmpty(value)) {
                        return value;
                    }
                    /** 查詢數(shù)據(jù)庫 **/
                    value = bizCall.call();

                    /** 數(shù)據(jù)庫無數(shù)據(jù)則返回**/
                    if (StringUtils.isEmpty(value)) {
                        return null;
                    }

                    /** 數(shù)據(jù)存入緩存 **/
                    redisClient.setex(key, dataExpireSeconds, value);
                    return value;
                } else {
                    if (!alwaysRetry) {
                        logger.warn("競爭分布式鎖失敗,key={}", key);
                        return null;
                    }
                    Thread.sleep(100L);
                    logger.warn("嘗試重新獲取數(shù)據(jù),key={}", key);
                }
            }
        } catch (Exception ex) {
            logger.error("getDistributeSafeError", ex);
            return null;
        } finally {
            if (getLockSuccess) {
                redisLockManager.unLock(key);
            }
        }
    }
}


4 分

我們首先看一個概念:讀寫比。互聯(lián)網(wǎng)場景中一般是讀多寫少,例如瀏覽20次訂單列表信息才會進行1次確認收貨,此時讀寫比例就是20:1。面對讀多寫少這種情況我們可以做什么呢?

我們可以部署多臺MySQL讀庫專門用來接收讀請求,主庫接收寫請求并通過binlog實時同步的方式將數(shù)據(jù)同步至讀庫。MySQL官方即提供這種能力,進行簡單配置即可。



那么客戶端怎么知道訪問讀庫還是寫庫呢?推薦使用ShardingSphere組件,通過配置將讀寫請求分別路由至讀庫或者寫庫。


5 拆

如果刪除了歷史數(shù)據(jù)并采用了其它存儲介質(zhì),也用了讀寫分離,但是單表壓力還是太大怎么辦?這時我們只能拆分數(shù)據(jù)表,即把單庫單表數(shù)據(jù)遷移到多庫多張表中。

假設(shè)有一個電商數(shù)據(jù)庫存放訂單、商品、支付三張業(yè)務(wù)表。隨著業(yè)務(wù)量越來越大,這三張業(yè)務(wù)數(shù)據(jù)表也越來越大,我們就以這個例子進行分析。


5.1 垂直拆分

垂直拆分就是按照業(yè)務(wù)拆分,我們將電商數(shù)據(jù)庫拆分成三個庫,訂單庫、商品庫。支付庫,訂單表在訂單庫,商品表在商品庫,支付表在支付庫。這樣每個庫只需要存儲本業(yè)務(wù)數(shù)據(jù),物理隔離不會互相影響。


5.2 水平拆分

按照垂直拆分方案,現(xiàn)在我們已經(jīng)有三個庫了,平穩(wěn)運行了一段時間。但是隨著業(yè)務(wù)增長,每個單庫單表的數(shù)據(jù)量也越來越大,逐漸到達瓶頸。

這時我們就要對數(shù)據(jù)表進行水平拆分,所謂水平拆分就是根據(jù)某種規(guī)則將單庫單表數(shù)據(jù)分散到多庫多表,從而減小單庫單表的壓力。

水平拆分策略有很多方案,最重要的一點是選好ShardingKey,也就是按照哪一列進行拆分,怎么分取決于我們訪問數(shù)據(jù)的方式。


5.2.1 范圍分片

現(xiàn)在我們要對訂單庫進行水平拆分,我們選擇的ShardingKey是訂單創(chuàng)建時間,拆分策略如下:

(1) 拆分為四個數(shù)據(jù)庫,分別存儲每個季度的數(shù)據(jù)
(2) 每個庫三張表,分別存儲每個月的數(shù)據(jù)

上述方法優(yōu)點是對范圍查詢比較友好,例如我們需要統(tǒng)計第一季度的相關(guān)數(shù)據(jù),查詢條件直接輸入時間范圍即可。



但是這個方案問題是容易產(chǎn)生熱點數(shù)據(jù)。例如雙11當天下單量特別大,就會導(dǎo)致11月這張表數(shù)據(jù)量特別大從而造成訪問壓力。


5.2.2 查表分片

查表法是根據(jù)一張路由表決定ShardingKey路由到哪一張表,每次路由時首先到路由表里查到分片信息,再到這個分片去取數(shù)據(jù)。

們分析一個查表法實際案例。Redis官方在3.0版本之后提供了集群方案Redis Cluster,其中引入了哈希槽(slot)這個概念。

一個集群固定有16384個槽,在集群初始化時這些槽會平均分配到Redis集群節(jié)點上。每個key請求最終落到哪個槽計算公式是固定的:

SLOT = CRC16(key) mod 16384

那么問題來了:一個key請求過來怎么知道去哪臺Redis節(jié)點獲取數(shù)據(jù)?這就要用到查表法思想。

(1) 客戶端連接任意一臺Redis節(jié)點,假設(shè)隨機訪問到為節(jié)點A

(2) 節(jié)點A根據(jù)key計算出slot值

(3) 每個節(jié)點都維護著slot和節(jié)點映射關(guān)系表

(4) 如果節(jié)點A查表發(fā)現(xiàn)該slot在本節(jié)點則直接返回數(shù)據(jù)給客戶端

(5) 如果節(jié)點A查表發(fā)現(xiàn)該slot不在本節(jié)點則返回給客戶端一個重定向命令,告訴客戶端應(yīng)該去哪個節(jié)點上請求這個key的數(shù)據(jù)

(6) 客戶端再向正確節(jié)點發(fā)起連接請求

查表法優(yōu)點是可以靈活制定路由策略,如果我們發(fā)現(xiàn)有的分片已經(jīng)成為熱點則修改路由策略。缺點是多一次查詢路由表操作增加耗時,而且路由表如果是單點也可能會有單點問題。


5.2.3 哈希分片

現(xiàn)在比較流行的分片方法是哈希分片,相較于范圍分片,哈希分片可以較為均勻?qū)?shù)據(jù)分散在數(shù)據(jù)庫中。我們現(xiàn)在將訂單庫拆分為4個庫編號為[0,3],每個庫4張表編號為[0,3],如下圖如所示:



我們現(xiàn)在使用orderId作為ShardingKey,那么orderId=100的訂單會保存在哪張表?我們來計算一下:由于是分庫分表,首先確定路由到哪一個庫,取模計算得到序號為0表示路由到db[0]

db_index = 100 % 4 = 0

庫確定了接著在db[0]進行取模表路由

table_index = 100 % 4 = 0

最終這條數(shù)據(jù)應(yīng)該路由至下表

db[0]_table[0]

最終計算結(jié)果如下圖所示:


在實際開發(fā)中最終路由到哪張表,并不需要我們自己算,因為有許多開源框架就可以完成路由功能,例如ShardingSphere、TDDL等等。



6 異

現(xiàn)在數(shù)據(jù)已經(jīng)使用哈希分片方法完成了水平拆分,我們選擇的ShardingKey是orderId。這時客戶端需要查詢orderId=111的數(shù)據(jù),查詢語句很簡單如下:

select * from order where orderId = 111

這個語句沒有問題,因為查詢條件包含orderId,可以路由到具體的數(shù)據(jù)表。

現(xiàn)在如果業(yè)務(wù)想要查詢用戶維度的數(shù)據(jù),希望查詢userId=222的數(shù)據(jù),現(xiàn)在問題來了:以下這個語句可以查出數(shù)據(jù)嗎?

select * from order where userId = 222

答案是可以,但是需要掃描所有庫的所有表,因為無法根據(jù)userId路由到具體某一張表,這樣時間成本會非常高,這種場景怎么辦呢?

這就要用到數(shù)據(jù)異構(gòu)的思想。數(shù)據(jù)異構(gòu)核心是用空間換時間,簡單一句話就是一份數(shù)據(jù)按照不同業(yè)務(wù)需求保存多份,這樣做是因為存儲硬件成本不是很高,而互聯(lián)網(wǎng)場景對響應(yīng)速度要求很高。

對于上述需要使用userId進行查詢的場景,我們完全可以新建庫和表,數(shù)量和結(jié)構(gòu)與訂單庫表完全一致,唯一不同點是ShardingKey改用userId,這樣就可以使用userId查詢了。

現(xiàn)在又引出一個新問題,業(yè)務(wù)不可能每次都將數(shù)據(jù)寫入多個數(shù)據(jù)源,這樣會帶來性能問題和數(shù)據(jù)一致行為。怎么解決老庫和新庫數(shù)據(jù)同步問題?我們可以使用阿里開源的canal組件解決這個問題,看一張官網(wǎng)介紹canal架構(gòu)圖:


canal組件的主要用途是基于MySQL數(shù)據(jù)庫增量日志解析,提供增量數(shù)據(jù)訂閱和消費服務(wù),工作原理如下:

(1) canal偽裝成為MySQL slave模擬交互協(xié)議向master發(fā)送dump協(xié)議

(2) master收到canal發(fā)送的dump請求,開始推送binlog給canal

(3) canal解析binlog并發(fā)送到存儲目的地,例如MySQL、Kafka、Elasticsearch

canal組件下游可以對接很多其它數(shù)據(jù)源,這樣給業(yè)務(wù)提供了更多選擇。我們可以像上述實例中新建用戶維度訂單表,也可以將數(shù)據(jù)存在ES中提供運營檢索能力等等。


7 熱

我們來分析這樣一個場景:社交業(yè)務(wù)有一張用戶關(guān)系表,主要記錄誰關(guān)注了誰。其中有一個明星粉絲特別多,如果以userId作為分片,那么其所在分片數(shù)據(jù)量就會特別大。

不僅分片數(shù)據(jù)量特別大,而且可以預(yù)見這個分片訪問頻率也會非常高。此時數(shù)據(jù)量大并且訪問頻繁,很有可能造成系統(tǒng)壓力。


7.1 熱點概念

我們將訪問行為稱為熱點行為,將訪問對應(yīng)的數(shù)據(jù)稱為熱點數(shù)據(jù)。我們通過實例來分析。

在電商雙11活動中百分之八十的訪問量會集中在百分之二十的商品上。用戶刷新、添加購物車、下單被稱為熱點行為,相應(yīng)商品數(shù)據(jù)就被稱為熱點數(shù)據(jù)。

在微博場景中大V發(fā)布一條消息會獲得大量訪問。用戶對這條消息的瀏覽、點贊、轉(zhuǎn)發(fā)、評論被稱為熱點行為,這條消息數(shù)據(jù)被稱為熱點數(shù)據(jù)。

在秒殺場景中參與秒殺的商品會獲得極大的瞬時訪問量。用戶對這個商品的頻繁刷新、點擊、下單被稱為熱點行為,參與秒殺的商品數(shù)據(jù)被稱為熱點數(shù)據(jù)。

我們必須將熱點數(shù)據(jù)進行一些處理,使得熱點訪問更加流暢,更是為了保護系統(tǒng)免于崩潰。我們從發(fā)現(xiàn)熱點數(shù)據(jù)、處理熱點數(shù)據(jù)來展開分析。


7.2 發(fā)現(xiàn)熱點數(shù)據(jù)

我們把發(fā)現(xiàn)熱點數(shù)據(jù)分為兩種方式:靜態(tài)發(fā)現(xiàn)和動態(tài)發(fā)現(xiàn)。

靜態(tài)發(fā)現(xiàn):在開始秒殺活動之前,參與商家一定知道哪些商品參與秒殺,那么他們可以提前將這些商品報備告知平臺。

在微博場景中,具有影響力的大V一般都很知名,網(wǎng)站運營同學(xué)可以提前知道。技術(shù)同學(xué)還可以通過分析歷史數(shù)據(jù)找出TOP N數(shù)據(jù)。對于這些可以提前預(yù)判的數(shù)據(jù),完全可以通過后臺系統(tǒng)上報,這樣系統(tǒng)可以提前做出預(yù)處理。

動態(tài)發(fā)現(xiàn):有些商品可能并沒有上報為熱點商品,但是在實際銷售中卻非常搶手。在微博場景中,有些話題熱度突然升溫。這些數(shù)據(jù)成為事實上的熱點數(shù)據(jù)。對于這些無法提前預(yù)判的數(shù)據(jù),需要動態(tài)進行判斷。

我們需要一個熱點發(fā)現(xiàn)系統(tǒng)去主動發(fā)現(xiàn)熱點數(shù)據(jù)。大體思路是首先異步收集訪問日志,再統(tǒng)計單位時間內(nèi)訪問頻次,當超過一定閾值時可以判斷為熱點數(shù)據(jù)。


7.3 處理熱點問題

(1) 熱點行為

熱點行為可以采取高頻檢測方式,如果發(fā)現(xiàn)頻率過高則進行限制。或者采用內(nèi)存隊列實現(xiàn)的生產(chǎn)者與消費者這種異步化方式,消費者根據(jù)能力處理請求。

(2) 熱點數(shù)據(jù)

處理熱點數(shù)據(jù)核心主要是根據(jù)業(yè)務(wù)形態(tài)來進行處理,我一般采用以下方案配合執(zhí)行:

(1) 選擇合適ShardingKey進行分庫分表
 
(2) 異構(gòu)數(shù)據(jù)至其它適合檢索的數(shù)據(jù)源例如ES

(3) 在MySQL之前設(shè)置緩存層

(4) 盡量不在MySQL進行耗時操作(例如聚合)


8 文章總結(jié)

本文我們詳細介紹處理單表數(shù)據(jù)量過大的六字口訣:刪、換、分、拆、異、熱。

這并不是意味這每次遇到單表數(shù)據(jù)量過大情況六種方案全部都要使用,例如拆分數(shù)據(jù)表成本確實比較高,會帶來分布式事務(wù)、數(shù)據(jù)難以聚合等問題,如果不分表可以解決那么就不要分表,核心還是根據(jù)自身業(yè)務(wù)情況選擇合適的方案。



該文章在 2023/5/19 11:30:05 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調(diào)度、堆場、車隊、財務(wù)費用、相關(guān)報表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務(wù)都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved